msksheet.cpp Aggiunta funzione set_column_justify msksheet.h Dichiarazione della funzione precedente git-svn-id: svn://10.65.10.50/trunk@2116 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			3646 lines
		
	
	
		
			78 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			3646 lines
		
	
	
		
			78 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <xvt.h>
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <colors.h>
 | 
						|
#include <defmask.h>
 | 
						|
#include <execp.h>
 | 
						|
#include <golem.h>
 | 
						|
#include <mailbox.h>
 | 
						|
#include <mask.h>
 | 
						|
#include <prefix.h> 
 | 
						|
#include <relation.h>
 | 
						|
#include <sheet.h>
 | 
						|
#include <tabutil.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <validate.h>
 | 
						|
#include <xvtility.h>
 | 
						|
#include <text.h>
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
#include <windows.h>
 | 
						|
#endif
 | 
						|
 | 
						|
HIDDEN TString256 fpark;
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Field Flags
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TMask_field::TField_Flags::TField_Flags()
 | 
						|
{
 | 
						|
  automagic = persistent   = FALSE;
 | 
						|
  enabled = enable_default = TRUE;
 | 
						|
  shown = show_default     = TRUE;
 | 
						|
  uppercase = rightjust    = FALSE;
 | 
						|
  zerofilled               = FALSE;
 | 
						|
  dirty = focusdirty       = FALSE;
 | 
						|
  roman = exchange         = FALSE;
 | 
						|
  firm = ghost             = FALSE;
 | 
						|
  password                 = FALSE;
 | 
						|
  trim                     = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
char TMask_field::TField_Flags::update(const char* f)
 | 
						|
{
 | 
						|
  for (const char* s = f; *s; s++)
 | 
						|
    switch(toupper(*s))
 | 
						|
    {
 | 
						|
    case ' ':  
 | 
						|
    case '_':
 | 
						|
      trim = FALSE; break;  
 | 
						|
    case '*':
 | 
						|
      password = TRUE; break;
 | 
						|
    case 'A':
 | 
						|
      automagic = persistent = TRUE; break;
 | 
						|
    case 'D': 
 | 
						|
      enable_default = enabled = FALSE; break;
 | 
						|
    case 'F': 
 | 
						|
      firm = persistent = TRUE; break;
 | 
						|
    case 'G': 
 | 
						|
      ghost = TRUE; break;
 | 
						|
    case 'H': 
 | 
						|
      show_default  = shown = FALSE; break;
 | 
						|
    case 'M': 
 | 
						|
      roman = TRUE; break;
 | 
						|
    case 'P': 
 | 
						|
      persistent = TRUE; break;
 | 
						|
    case 'R': 
 | 
						|
      rightjust = TRUE; break;
 | 
						|
    case 'U': 
 | 
						|
      uppercase = TRUE; break;
 | 
						|
    case 'V': 
 | 
						|
      exchange = TRUE; break;
 | 
						|
    case 'Z': 
 | 
						|
      zerofilled = TRUE; break;
 | 
						|
      default :  
 | 
						|
      CHECKS(0, "FLAG sconosciuto in ", f);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return *s;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMask_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
int TMask_field::_x;          // Position of the field
 | 
						|
int TMask_field::_y;
 | 
						|
int TMask_field::_width;
 | 
						|
TString80 TMask_field::_prompt;
 | 
						|
 | 
						|
TMask_field::TMask_field(TMask* m)
 | 
						|
: _mask(m), _win(NULL_WIN), _promptwin(NULL_WIN), _dlg(0),
 | 
						|
  _keys(0), _groups(0), _help(0), _handler(NULL),
 | 
						|
  _validate_func(-1), _validate_parms(1), _field(NULL)
 | 
						|
{
 | 
						|
  _x = -1;
 | 
						|
  _y = -1;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TMask_field::~TMask_field()
 | 
						|
{
 | 
						|
  if (_field) delete _field;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
const char* TMask_field::class_name() const
 | 
						|
{ return "Field"; }
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
word TMask_field::class_id() const
 | 
						|
{ return CLASS_FIELD; }
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
bool TMask_field::ok() const
 | 
						|
{ return win() != NULL_WIN && dlg() >= -1; }
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::parse_head(TScanner&)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
short TMask_field::atodlg(const char* s) const
 | 
						|
{
 | 
						|
  short d = s ? atoi(s) : 0;
 | 
						|
 | 
						|
#ifdef DBG
 | 
						|
  if (d == 0 || d < -1 || d > 1000)
 | 
						|
  {
 | 
						|
    yesnofatal_box("Identificatore non valido nel campo %d: '%s'", dlg(), s);
 | 
						|
    d = -1;
 | 
						|
  }
 | 
						|
#endif  
 | 
						|
 | 
						|
  return d;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Costruisce il campo
 | 
						|
void TMask_field::construct(
 | 
						|
  short id,            // @parm Identificatore del campo
 | 
						|
  const char* prompt,  // @parm Prompt del campo
 | 
						|
  int x,               // @parm Posizione in x (in caratteri) del campo nella maschera
 | 
						|
  int y,               // @parm Posizione in y (in caratteri) del campo nella maschera
 | 
						|
  int len,             // @parm Lunghezza vidibile del campo
 | 
						|
  WINDOW parent,       // @parm Finestra padre alla quale assegnare il campo
 | 
						|
  const char* flags,   // @parm Flags del campo (default "")
 | 
						|
  int width)           // @parm Lunghezza del campo
 | 
						|
  // @parm TScanner& | scanner | File dal quale leggere leggere le informazioni
 | 
						|
 | 
						|
  // @syntax void construct(TScanner& scanner, WINDOW parent);  
 | 
						|
  // @syntax void construct(short id, const char* prompt, int x, int y, int len, WINDOW parent, const char* flags, int width);
 | 
						|
  //                            
 | 
						|
  // @comm E' possibile costruire il campo leggendo direttamente dal file, oppure passare alla funzione
 | 
						|
  //                     tutti i parametri necessari alla definizione del campo stesso
 | 
						|
{
 | 
						|
  _x = x; _y = y;
 | 
						|
  _prompt = prompt;
 | 
						|
  _size = len;
 | 
						|
  if (class_id() == CLASS_REAL_FIELD)
 | 
						|
  {
 | 
						|
    ((TReal_field*)this)->set_decimals(width);
 | 
						|
    _width = _size;
 | 
						|
  }
 | 
						|
  else _width = width < 1 ? _size : width;
 | 
						|
  _dlg = id;
 | 
						|
  _flags.update(flags);
 | 
						|
 | 
						|
  create(parent);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TMask_field::construct(TScanner& scanner, WINDOW parent)
 | 
						|
{
 | 
						|
  _dlg = atodlg(scanner.pop());
 | 
						|
  parse_head(scanner);
 | 
						|
  _prompt.cut(0);
 | 
						|
  
 | 
						|
  scanner.popkey();                 // BEGIN
 | 
						|
#ifdef DBG  
 | 
						|
  if (scanner.key() != "BE")          
 | 
						|
  {
 | 
						|
    yesnofatal_box("Testata errata o BEGIN mancante nel campo %d", _dlg);
 | 
						|
    scanner.push();
 | 
						|
  }
 | 
						|
#endif          
 | 
						|
 | 
						|
  while(scanner.popkey() != "EN")       // END of control
 | 
						|
    parse_item(scanner);
 | 
						|
  create(parent);
 | 
						|
}
 | 
						|
 | 
						|
void TMask_field::set_back_color(COLOR c) const
 | 
						|
{
 | 
						|
  xvt_set_ctrl_back_color(win(), c);
 | 
						|
}
 | 
						|
 | 
						|
bool TMask_field::parse_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  if (scanner.key() == "PR")                    // PROMPT
 | 
						|
  {
 | 
						|
    _x = scanner.integer();
 | 
						|
    _y  = scanner.integer();
 | 
						|
    _prompt = scanner.string();
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "FL")                    // FLAG
 | 
						|
  {
 | 
						|
    const char* f = scanner.string();
 | 
						|
    return _flags.update(f) == '\0';
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "FI")                    // FIELD
 | 
						|
  {
 | 
						|
    CHECKD(_field == NULL, "Only one FIELD, please: ", dlg());
 | 
						|
    _field = new TFieldref(scanner.line(), 0);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "HE")                    // HELP
 | 
						|
  {
 | 
						|
    _help = scanner.string();
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "KE")                    // KEY
 | 
						|
  {
 | 
						|
    _keys.set(scanner.line());
 | 
						|
    _keys.set(0L);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( scanner.key() == "CU")                   // CUSTOM DATA
 | 
						|
  {
 | 
						|
    _userdata.add(scanner.string());
 | 
						|
    return TRUE;
 | 
						|
  } 
 | 
						|
 | 
						|
  if (scanner.key() == "ME")
 | 
						|
  {
 | 
						|
    if (_message.objptr(0) == 0)
 | 
						|
      _message.add(new TToken_string(64), 0);
 | 
						|
    TToken_string& ts = (TToken_string&)_message[0];
 | 
						|
    ts.add(scanner.line().strip_spaces());
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "GR")
 | 
						|
  {
 | 
						|
    _groups.set(scanner.line());
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "VA")
 | 
						|
  {                    
 | 
						|
    const char* n = scanner.pop();
 | 
						|
    _validate_func = isdigit(*n) ? atoi(n) : -1;
 | 
						|
#ifdef DBG    
 | 
						|
    if (_validate_func < 0)
 | 
						|
      return yesnofatal_box("Funzione di validazione '%s' errata nel campo %d", n, dlg());
 | 
						|
#endif
 | 
						|
 | 
						|
    const int _nparms = scanner.integer();
 | 
						|
#ifdef DBG    
 | 
						|
    if (_nparms < 0 || _nparms > 100)
 | 
						|
      return yesnofatal_box("Numero di parametri VALIDATE errato nel campo %d: %d", dlg(), _nparms);
 | 
						|
#endif
 | 
						|
 | 
						|
    for(int i = 0; i < _nparms; i++)
 | 
						|
      _validate_parms.add(scanner.operand());
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "WA")
 | 
						|
  {
 | 
						|
    _warning = scanner.string();
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
long TMask_field::default_flags() const
 | 
						|
{
 | 
						|
  long f = CTL_FLAG_NATIVE_JUST;
 | 
						|
 | 
						|
  if (_flags.show_default == FALSE)   f |= CTL_FLAG_INVISIBLE;
 | 
						|
  if (_flags.enable_default == FALSE) f |= CTL_FLAG_DISABLED;
 | 
						|
 | 
						|
  return f;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
// @mfunc Crea la finestra del controllo
 | 
						|
//
 | 
						|
// @rdesc Ritorna la finestra creata
 | 
						|
WINDOW TMask_field::wincreate(
 | 
						|
  WIN_TYPE ct,        // @parm Tipo di finestra da creare
 | 
						|
  short dx,           // @parm Larghezza iniziale della finestra
 | 
						|
  short dy,           // @parm Altezza iniziale della finestra
 | 
						|
  const char* title,  // @parm Titolo della finestra
 | 
						|
  WINDOW parent,      // @parm Finestra padre di quella da creare
 | 
						|
  long flags)         // @parm fleg della finestra
 | 
						|
{
 | 
						|
  _win = xvt_create_control(ct,
 | 
						|
                            _x, _y, dx, dy,
 | 
						|
                            (char*)title,
 | 
						|
                            parent,
 | 
						|
                            flags | default_flags(),
 | 
						|
                            PTR_LONG(this),
 | 
						|
                            _dlg);
 | 
						|
 | 
						|
  return _win;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
WINDOW TMask_field::parent() const
 | 
						|
{ return xvt_vobj_get_parent(win()); }
 | 
						|
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
// @mfunc Crea il prompt del controllo
 | 
						|
//
 | 
						|
// @rdesc Ritorna la lunghezza del prompt creato
 | 
						|
int TMask_field::create_prompt(
 | 
						|
  WINDOW parent, // @parm Finestra padre alla quale assegnare il prompt del controllo
 | 
						|
  int width,     // @parm Larghezza del controllo
 | 
						|
  int heigth)    // @parm Altezza del controllo
 | 
						|
{
 | 
						|
  const WIN_TYPE wt = (heigth < 3) ? WC_TEXT : WC_GROUPBOX;
 | 
						|
  if (width < 1) width = _prompt.len() - (_prompt[0] == '@' ? 2 : 0);
 | 
						|
  _prompt.rtrim();              // Could save some bytes
 | 
						|
 | 
						|
  if (width)
 | 
						|
  {
 | 
						|
    const long flags = default_flags() & (~CTL_FLAG_DISABLED); //  Static controls shouldn't be grayed  
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
    const int k = _prompt.find('~');
 | 
						|
    if (k >= 0) _prompt[k] = '&';
 | 
						|
#endif
 | 
						|
    _promptwin = xvt_create_control
 | 
						|
      (
 | 
						|
       wt,
 | 
						|
       _x, _y, width, heigth,
 | 
						|
       _prompt,
 | 
						|
       parent,
 | 
						|
       flags,
 | 
						|
       0L,
 | 
						|
       -1
 | 
						|
       );
 | 
						|
  }
 | 
						|
  if (_x == -1 && _y == -1)
 | 
						|
  {
 | 
						|
    _x = 1;
 | 
						|
    _y = 30;
 | 
						|
  }
 | 
						|
  return width;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::destroy()
 | 
						|
{
 | 
						|
  if (_win)
 | 
						|
  { xvt_vobj_destroy(_win); _win = NULL_WIN; }
 | 
						|
  if (_promptwin)
 | 
						|
  { xvt_vobj_destroy(_promptwin); _promptwin = NULL_WIN; }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  _width = _prompt.len();
 | 
						|
  if (_width)
 | 
						|
    wincreate(WC_TEXT, _width, 1, _prompt, parent, CTL_FLAG_LEFT_JUST);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
// @mfunc Abilita/disabilita il campo (lo rende scrivibile)
 | 
						|
void TMask_field::enable(
 | 
						|
  bool on) // @parm Operazione da svolgere:
 | 
						|
  //
 | 
						|
  // @flag TRUE | Abilita il campo (default)
 | 
						|
  // @flag FALSE | Disabilita il campo
 | 
						|
{
 | 
						|
  const word c = class_id();
 | 
						|
  if (c != CLASS_FIELD)
 | 
						|
  {
 | 
						|
    xvt_vobj_set_enabled(_win, on);
 | 
						|
    _flags.enabled = on;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::enable_default()
 | 
						|
{
 | 
						|
  const bool ed = _flags.enable_default;
 | 
						|
  enable(ed);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
// @mfunc Permette di rendere visibile/invisibile un campo
 | 
						|
void TMask_field::show(
 | 
						|
  bool on) // @parm Operazione da svolgere:
 | 
						|
  //
 | 
						|
  // @flag TRUE | Rendere visibile il campo (default)
 | 
						|
  // @flag FALSE | Rendere invisibile il campo
 | 
						|
{
 | 
						|
  xvt_vobj_set_visible(_win, on);
 | 
						|
  if (_promptwin != NULL_WIN)
 | 
						|
    xvt_vobj_set_visible(_promptwin, on);
 | 
						|
  _flags.shown = on;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::show_default()
 | 
						|
{          
 | 
						|
  const bool sd = _flags.show_default;
 | 
						|
  show(sd);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
bool TMask_field::active() const
 | 
						|
{
 | 
						|
  return enabled() && shown() && class_id() != CLASS_FIELD;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
word TMask_field::last_key() const
 | 
						|
{
 | 
						|
  long u = _keys.last_one();
 | 
						|
  if (u < 0) u = 0;
 | 
						|
  return (word)u;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
void TMask_field::reset_key(byte key)
 | 
						|
{
 | 
						|
  CHECK(key>0, "Can't reset key 0");
 | 
						|
  _keys.reset(long(key));
 | 
						|
  if (last_key()==0) _keys.reset(0L);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TMask_field::set_dirty(bool d) 
 | 
						|
{                
 | 
						|
  if (_flags.dirty == 3 && d == FALSE)
 | 
						|
    return;
 | 
						|
  _flags.dirty = d; 
 | 
						|
  set_focusdirty(d); 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
const char* TMask_field::get_window_data() const
 | 
						|
{
 | 
						|
  return xvt_vobj_get_title(win(), (char*)(const char*)fpark, fpark.size());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
void TMask_field::set_window_data(const char* data)
 | 
						|
{
 | 
						|
  if (data != NULL)
 | 
						|
    xvt_vobj_set_title(win(), (char*)data);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::set_field_data(const char*)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
const char* TMask_field::get_field_data() const
 | 
						|
{ return NULL; }
 | 
						|
 | 
						|
 | 
						|
// @mfunc Permette di dare la stessa formattazione del campo della maschera
 | 
						|
//
 | 
						|
// @rdesc Ritorna la stringa formattata
 | 
						|
const char* TMask_field::picture_data(
 | 
						|
  const char* data, // @parm Stringa da dare il formato
 | 
						|
  bool video) const // @parm Se TRUE permette di visualizzare la stringa a video
 | 
						|
  
 | 
						|
  // @comm Utilizzata soprattutto dagli sheet che in questo modo possono formattare
 | 
						|
  //             il contenuto delle celle con lo stesso formato deglia altri campi della maschera
 | 
						|
  //             dell stesso tipo.        
 | 
						|
{            
 | 
						|
  if (video) 
 | 
						|
  {
 | 
						|
    fpark = data;
 | 
						|
    fpark.trim();
 | 
						|
    if (_flags.uppercase) 
 | 
						|
      fpark.upper();
 | 
						|
    return fpark;
 | 
						|
  }  
 | 
						|
  return data;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
const char* TMask_field::prompt() const
 | 
						|
{
 | 
						|
  if (_promptwin != NULL_WIN)
 | 
						|
    _prompt = xvt_get_title(_promptwin);
 | 
						|
  else
 | 
						|
    _prompt = "";
 | 
						|
 | 
						|
  return _prompt;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
void TMask_field::set_field(const TString& fr)
 | 
						|
{
 | 
						|
  if (_field != NULL)  
 | 
						|
    *_field = fr;
 | 
						|
  else
 | 
						|
    _field = new TFieldref(fr, 0);
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TMask_field::reset()
 | 
						|
{
 | 
						|
  if (!_flags.persistent && class_id() != CLASS_FIELD)
 | 
						|
    set("");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 00%
 | 
						|
void TMask_field::set_prompt(const char* p)
 | 
						|
{
 | 
						|
  if (_promptwin != NULL_WIN)
 | 
						|
    xvt_vobj_set_title(_promptwin, (char*) p);
 | 
						|
 | 
						|
  if (*p++ == '@')
 | 
						|
  {
 | 
						|
    if (toupper(*p) == 'U')
 | 
						|
      xvt_set_font(_win, "", XVT_FS_UNDERLINE, CHARY-12);
 | 
						|
    if (toupper(*p) == 'B')
 | 
						|
      xvt_set_font(_win, "", XVT_FS_BOLD, CHARY-12);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    xvt_set_font(_win, "", XVT_FS_NONE);  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TMask_field::set(const char* s)
 | 
						|
{                
 | 
						|
  if (mask().is_running())
 | 
						|
  {
 | 
						|
    set_window_data(s);
 | 
						|
    set_dirty();
 | 
						|
  }
 | 
						|
  else
 | 
						|
    set_field_data(s);
 | 
						|
}
 | 
						|
 | 
						|
TString& TMask_field::get() const
 | 
						|
{
 | 
						|
  static TString256 gpark;
 | 
						|
 | 
						|
  if (mask().is_running())
 | 
						|
    gpark = get_window_data();
 | 
						|
  else
 | 
						|
    gpark = get_field_data();
 | 
						|
 | 
						|
  if (_flags.trim) gpark.trim();
 | 
						|
  return gpark;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TMask_field::undo()
 | 
						|
{
 | 
						|
  set_window_data(get_field_data());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TMask_field::autoload(const TRelation* r)
 | 
						|
{
 | 
						|
  if (_field)
 | 
						|
  {                      
 | 
						|
    set(_field->read(r));
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TMask_field::autosave(TRelation* r) const
 | 
						|
{
 | 
						|
  if (_field)
 | 
						|
  {
 | 
						|
    _field->write(get(), r);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 50%
 | 
						|
HIDDEN void modify_list(bool add, TMask_field& f, TToken_string& msg)
 | 
						|
{
 | 
						|
#ifdef DBG
 | 
						|
  if (f.class_id() != CLASS_LIST_FIELD)
 | 
						|
  {
 | 
						|
    yesnofatal_box("Can't add/delete items of non list-box field %d", f.dlg());
 | 
						|
    return;
 | 
						|
  }  
 | 
						|
#endif  
 | 
						|
  TList_field& l = (TList_field&)f;
 | 
						|
  
 | 
						|
  TToken_string item(16); 
 | 
						|
  item = msg.get(); 
 | 
						|
  if (add) item.add(msg.get()); 
 | 
						|
  item.strip("\"'");
 | 
						|
  if (add)
 | 
						|
    l.add_item(item);
 | 
						|
  else
 | 
						|
    l.delete_item(item);  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 99%
 | 
						|
HIDDEN const char* copy_value(TToken_string& msg, const TString& val)
 | 
						|
{
 | 
						|
  int from = msg.get_int()-1;
 | 
						|
  int to = -1;
 | 
						|
  if (from < 0) from = 0;
 | 
						|
  else to = msg.get_int();
 | 
						|
  return val.sub(from, to);
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN void run_app(const TMask& mask, TToken_string& msg)
 | 
						|
{
 | 
						|
  TFilename a;
 | 
						|
  
 | 
						|
  for (const char* m = msg.get(1); m; m = msg.get())
 | 
						|
  {
 | 
						|
    if (a.not_empty())                    
 | 
						|
      a << ' ';
 | 
						|
    
 | 
						|
    for (const char* f = m; *f; f++)
 | 
						|
    {
 | 
						|
      if (*f == '#') 
 | 
						|
      {
 | 
						|
        const int id = atoi(++f);
 | 
						|
        a << mask.get(id);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        a << *f;
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  TExternal_app app(a);
 | 
						|
  app.run();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TMask_field::send_key(KEY k, short to) 
 | 
						|
{ 
 | 
						|
  mask().send_key(k, to, this); 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
bool TMask_field::do_message(int num)
 | 
						|
{               
 | 
						|
  const int MAX_CMD = 17;
 | 
						|
  static const char* commands[MAX_CMD] =
 | 
						|
  {
 | 
						|
    "ADD",         //  0
 | 
						|
    "CLEAR",       //  1
 | 
						|
    "CO",          //  2
 | 
						|
    "DEL",         //  3
 | 
						|
    "DIRTY",       //  4
 | 
						|
    "DISABLE",     //  5
 | 
						|
    "ENABLE",      //  6
 | 
						|
    "ENABLEDEF",   //  7 
 | 
						|
    "EXIT",        //  8
 | 
						|
    "HIDE",        //  9 
 | 
						|
    "NORMAL",      // 10
 | 
						|
    "PUSH",        // 11
 | 
						|
    "REQUIRED",    // 12
 | 
						|
    "RESET",       // 13
 | 
						|
    "RU",          // 14  
 | 
						|
    "SHOW",        // 15
 | 
						|
    "UNDO"         // 16
 | 
						|
    };
 | 
						|
 | 
						|
  TToken_string* message = (TToken_string*)_message.objptr(num);
 | 
						|
  if (message == NULL || message->empty()) return FALSE;
 | 
						|
 | 
						|
  TToken_string msg(16, ',');
 | 
						|
  TString256 value;
 | 
						|
 | 
						|
  for (const char* m = message->get(0); m && *m; m = message->get())
 | 
						|
  {
 | 
						|
    KEY key = 0;
 | 
						|
    msg = m;
 | 
						|
    value = msg.get();
 | 
						|
    const char* dlg = msg.get();
 | 
						|
    
 | 
						|
    int cmd = -1;
 | 
						|
    if (isalpha(value[0]))                       // binary search
 | 
						|
    {         
 | 
						|
      int f = 0, l = MAX_CMD-1;                    
 | 
						|
      while (TRUE)
 | 
						|
      {
 | 
						|
        cmd = (f+l)>>1;                          
 | 
						|
        const int cmp = strcmp(value, commands[cmd]);
 | 
						|
        if (cmp == 0) break;
 | 
						|
        if (cmp > 0) f = cmd+1;
 | 
						|
        else         l = cmd-1;
 | 
						|
        if (f > l) 
 | 
						|
        {
 | 
						|
          cmd = -1;
 | 
						|
          break;
 | 
						|
        }  
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (cmd == 8)
 | 
						|
    {
 | 
						|
      mask().stop_run(atoi(dlg));
 | 
						|
      continue;
 | 
						|
    } else 
 | 
						|
      if (cmd == 14)
 | 
						|
      {
 | 
						|
        run_app(mask(), msg); 
 | 
						|
        continue;
 | 
						|
      }  
 | 
						|
 | 
						|
    short fld = (dlg && dlg[0] > ' ') ? atodlg(dlg) : 0;
 | 
						|
    bool broadcast = dlg && strchr(dlg, '@');
 | 
						|
    if (value[0] == '"') value = value.strip("\"'");
 | 
						|
    else switch (cmd)
 | 
						|
    {
 | 
						|
    case 0:
 | 
						|
      modify_list(TRUE, mask().field(fld), msg); continue;
 | 
						|
    case 1:
 | 
						|
      key = 11000+'c'; break;
 | 
						|
    case 2:
 | 
						|
      value = copy_value(msg, get()); break;
 | 
						|
    case 3:
 | 
						|
      modify_list(FALSE, mask().field(fld), msg); continue;
 | 
						|
    case 4:
 | 
						|
      mask().field(fld).set_dirty(); continue;
 | 
						|
    case 5:
 | 
						|
      key = 11000+'d'; break;
 | 
						|
    case 6:
 | 
						|
      key = 11000+'e'; break;
 | 
						|
    case 7:  
 | 
						|
      key = 11000+'E'; break;
 | 
						|
    case 9:
 | 
						|
      key = 11000+'h'; break;
 | 
						|
    case 10:
 | 
						|
      mask().efield(fld).check_type(CHECK_NORMAL); continue;
 | 
						|
    case 11:
 | 
						|
      key = K_SPACE; break;
 | 
						|
    case 12:
 | 
						|
      mask().efield(fld).check_type(CHECK_REQUIRED); continue;
 | 
						|
    case 13:
 | 
						|
      key = K_F2; break;
 | 
						|
    case 15:
 | 
						|
      key = 11000+'s'; break;
 | 
						|
    case 16:
 | 
						|
      key = K_F3; break;
 | 
						|
    default:                        
 | 
						|
      key = atoi(value);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (key)
 | 
						|
    {
 | 
						|
      if (key > 0)
 | 
						|
      {
 | 
						|
        if (broadcast) fld = -fld;
 | 
						|
        send_key(key, fld);
 | 
						|
      }  
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      // Setta a value il campo fld solo se ha un valore diverso da value
 | 
						|
      if (broadcast)
 | 
						|
      {
 | 
						|
        for (int i = 0; i < mask().fields(); i++)
 | 
						|
        {
 | 
						|
          TMask_field& f = mask().fld(i);
 | 
						|
          if (f.in_group((int)fld))
 | 
						|
          {
 | 
						|
            const char* prev = f.get();
 | 
						|
            if (value != prev)
 | 
						|
            {
 | 
						|
              f.set(value);
 | 
						|
              if (f.shown() || f.ghost())
 | 
						|
                f.on_hit();
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        TMask_field& f = mask().field(fld);
 | 
						|
        const char* prev = f.get();
 | 
						|
        if (value != prev)
 | 
						|
        {
 | 
						|
          f.set(value);
 | 
						|
          if (f.shown() || f.ghost())
 | 
						|
            f.on_hit();
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TMask_field::test_focus_change()
 | 
						|
{       
 | 
						|
  bool ok = TRUE; 
 | 
						|
  if (focusdirty()) ok = on_key(K_TAB);             // Comportamento normale
 | 
						|
  else if (is_edit() && in_key(1)) ok = on_hit();   // Serve per eseguire gli handler autoprementi
 | 
						|
  return ok;  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
bool TMask_field::on_hit()
 | 
						|
{
 | 
						|
  if (_handler)
 | 
						|
  {
 | 
						|
    bool ok = _handler(*this, is_edit() ? K_TAB : K_SPACE);
 | 
						|
    if (!ok) return FALSE;
 | 
						|
  }
 | 
						|
  do_message(0);
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Permette di spedire il check
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato del check:
 | 
						|
//
 | 
						|
// @flag TRUE | Se il check ha dato esito positivo
 | 
						|
// @flag FALSE | Se il check ha dato esito negativo
 | 
						|
bool TMask_field::to_check(
 | 
						|
  KEY k,               // @parm Tasto da passare al campo come simulazione di inizio controllo
 | 
						|
  bool checkrun) const // @parm Permette di testare sanche e la maschera e' in esecuzione
 | 
						|
{   
 | 
						|
  bool yes = (k == K_TAB && focusdirty()) || (k == K_ENTER && dirty());
 | 
						|
  
 | 
						|
  if (!yes && checkrun)
 | 
						|
    yes = k == K_TAB && !mask().is_running();
 | 
						|
  
 | 
						|
  return yes;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
bool TMask_field::on_key(KEY key)
 | 
						|
{
 | 
						|
  if (key > 11000)
 | 
						|
  {
 | 
						|
    switch(key-11000)
 | 
						|
    {
 | 
						|
    case 'E':
 | 
						|
      enable_default(); break;
 | 
						|
    case 'c':
 | 
						|
      reset(); on_hit();
 | 
						|
    case 'd':
 | 
						|
      disable(); break;
 | 
						|
    case 'e':
 | 
						|
      enable(); break;
 | 
						|
    case 'h':
 | 
						|
      hide(); break;
 | 
						|
    case 's':
 | 
						|
      show(); break;
 | 
						|
#ifdef DBG              
 | 
						|
      default :
 | 
						|
      return yesnofatal_box("Invalid key sent to field %d: %d", dlg(), key);
 | 
						|
#endif          
 | 
						|
    }
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  switch(key)
 | 
						|
  {
 | 
						|
  case K_SPACE:
 | 
						|
    set_dirty();
 | 
						|
    break;
 | 
						|
  case K_PREV:
 | 
						|
  case K_NEXT:
 | 
						|
    send_key(key, 0);
 | 
						|
    break;
 | 
						|
  case K_F1:
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
    if (fexist("prassi.hlp"))
 | 
						|
    {
 | 
						|
      struct MULTIGUY
 | 
						|
      {
 | 
						|
        UINT mkSize;
 | 
						|
        BYTE mkKeylist;
 | 
						|
        char mkKeyphrase[16];
 | 
						|
      } mk;
 | 
						|
      
 | 
						|
      TFilename topic(mask().source_file()); topic.ext("");
 | 
						|
      mk.mkSize = sizeof(MULTIGUY);
 | 
						|
      mk.mkKeylist = 'M';
 | 
						|
      strcpy(mk.mkKeyphrase, topic);
 | 
						|
      
 | 
						|
      TFilename hlp("prassi.hlp");
 | 
						|
      const TString16 mod(topic.left(2));
 | 
						|
      if (mod != "ba") hlp.insert(mod, 0);
 | 
						|
      
 | 
						|
      HWND hwnd = (HWND)xvt_vobj_get_attr(TASK_WIN, ATTR_NATIVE_WINDOW);
 | 
						|
      WinHelp(hwnd, hlp, HELP_MULTIKEY, (DWORD)&mk);
 | 
						|
      set_focus();
 | 
						|
      break;
 | 
						|
    }
 | 
						|
#endif  
 | 
						|
  case K_SHIFT+K_F1:
 | 
						|
    if (_help.not_empty())
 | 
						|
      message_box(_help);
 | 
						|
    else 
 | 
						|
      beep();
 | 
						|
    set_focus();
 | 
						|
    break;
 | 
						|
  case K_F11:
 | 
						|
  {          
 | 
						|
    const char* c = "";
 | 
						|
    if (field())
 | 
						|
      c = field()->name();
 | 
						|
    message_box("State utilizzando il campo %d della maschera '%s'\n"
 | 
						|
                "corrispondente al campo su file '%s'",
 | 
						|
                dlg(), (const char*)mask().source_file(), c);
 | 
						|
    set_focus();            
 | 
						|
  }  
 | 
						|
    break;
 | 
						|
    
 | 
						|
  case K_F2:
 | 
						|
    if (is_edit()) set("");
 | 
						|
    else reset();
 | 
						|
    set_dirty();
 | 
						|
    break;
 | 
						|
  case K_F3:
 | 
						|
    undo();
 | 
						|
    set_dirty();
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (_handler)
 | 
						|
    return _handler(*this, key);
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void TMask_field::highlight() const
 | 
						|
{
 | 
						|
  xvt_scr_set_focus_vobj(win());
 | 
						|
}
 | 
						|
 | 
						|
void TMask_field::set_focus() const
 | 
						|
{                                                
 | 
						|
  const bool force = mask().is_running();
 | 
						|
  mask().set_focus_win(win(), force);
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN char* const _msg = &__tmp_string[512];
 | 
						|
#define build_msg() va_list argptr;va_start(argptr,fmt);vsprintf(_msg,fmt,argptr);va_end(argptr)
 | 
						|
 | 
						|
// @mfunc Crea una error-box relativo al campo (chiama <f error_box>)
 | 
						|
//
 | 
						|
// @rdesc Ritorna sempre FALSE
 | 
						|
bool TMask_field::error_box(
 | 
						|
  const char* fmt,  // @parm Formato della stringa da scrivere
 | 
						|
  ...) const        // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
 | 
						|
  
 | 
						|
  // @comm Se il campo e'       uno sheet viene aggiornata la barra di stato, altrimenti
 | 
						|
  //             viene creata una finestra di errore normale.
 | 
						|
  
 | 
						|
{
 | 
						|
  build_msg();
 | 
						|
  if (mask().is_sheetmask() && !mask().is_running())
 | 
						|
  {                       
 | 
						|
    xvt_statbar_set(_msg);
 | 
						|
    beep();
 | 
						|
  }  
 | 
						|
  else
 | 
						|
  {
 | 
						|
    set_focus();
 | 
						|
    ::error_box("%s", _msg);
 | 
						|
    set_focus();
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TMask_field::message_box(const char* fmt, ...) const
 | 
						|
{                         
 | 
						|
  set_focus();
 | 
						|
  build_msg();
 | 
						|
  ::message_box("%s", _msg);
 | 
						|
  set_focus();
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Crea una warning-box relativo al campo (chiama <f warning_box>)
 | 
						|
//
 | 
						|
// @rdesc Ritorna sempre FALSE
 | 
						|
bool TMask_field::warning_box(
 | 
						|
  const char* fmt,  // @parm Formato della stringa da scrivere
 | 
						|
  ...) const        // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
 | 
						|
  
 | 
						|
  // @comm Se il campo e'       uno sheet viene aggiornata la barra di stato, altrimenti
 | 
						|
  //             viene creata una finestra di warning normale.
 | 
						|
{                         
 | 
						|
  build_msg();
 | 
						|
  
 | 
						|
  if (mask().is_sheetmask() && !mask().is_running())
 | 
						|
  {
 | 
						|
    xvt_statbar_set(_msg);
 | 
						|
    beep();
 | 
						|
  }  
 | 
						|
  else
 | 
						|
  {
 | 
						|
    set_focus();
 | 
						|
    ::warning_box("%s", _msg);
 | 
						|
    set_focus();
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TMask_field::yesno_box(const char* fmt, ...) const
 | 
						|
{                         
 | 
						|
  set_focus();
 | 
						|
  build_msg();
 | 
						|
  const bool yes = ::yesno_box("%s", _msg);
 | 
						|
  set_focus();
 | 
						|
  return yes;
 | 
						|
}
 | 
						|
 | 
						|
KEY TMask_field::yesnocancel_box(const char* fmt, ...) const
 | 
						|
{                         
 | 
						|
  set_focus();
 | 
						|
  build_msg();
 | 
						|
  const KEY k = ::yesnocancel_box("%s", _msg);
 | 
						|
  set_focus();
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TList_sheet
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TList_sheet::TList_sheet(TEdit_field* f, const char* caption, const char* head)
 | 
						|
: _fld(f), _row(-1)
 | 
						|
{
 | 
						|
  _sheet = new TArray_sheet(-1, -1, 0, 0, caption, head); 
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TList_sheet::~TList_sheet()
 | 
						|
{
 | 
						|
  delete _sheet;
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TMask_field& TList_sheet::field(short id) const
 | 
						|
{ return field().mask().field(id); }
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TList_sheet::read_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  TToken_string ts(scanner.string());
 | 
						|
  _sheet->add(ts);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TList_sheet::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  _inp_id.add(scanner.pop());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TList_sheet::parse_output(TScanner& scanner)
 | 
						|
{
 | 
						|
  _out_id.add(scanner.pop());
 | 
						|
}
 | 
						|
 | 
						|
// il numero di riga selezionata
 | 
						|
int TList_sheet::do_input()
 | 
						|
{
 | 
						|
  if (_inp_id.empty()) return -2;          // List empty!
 | 
						|
 | 
						|
  _inp_id.restart();
 | 
						|
  TToken_string rowsel(80);
 | 
						|
 | 
						|
  for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get())
 | 
						|
  {
 | 
						|
    if (*fld == '"')
 | 
						|
    {
 | 
						|
      rowsel.add(fld+1);
 | 
						|
      if (rowsel.not_empty()) rowsel.cut(rowsel.len()-1);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      const short id  =  _fld->atodlg(fld);
 | 
						|
      if (id > 0) rowsel.add(field().mask().get(id));
 | 
						|
      else rowsel.add("");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  TString80 fd, it;
 | 
						|
  for (int i = 0 ; i < _sheet->items(); i++)
 | 
						|
  {
 | 
						|
    TToken_string& ts =_sheet->row(i);
 | 
						|
 | 
						|
    ts.restart();
 | 
						|
    for ( const char* item = rowsel.get(0); item ; item = rowsel.get())
 | 
						|
    {
 | 
						|
      it = item; it.trim();
 | 
						|
      fd = ts.get(); fd.trim();
 | 
						|
      if (fd != it) break;
 | 
						|
    }
 | 
						|
    if (!item) return i;
 | 
						|
  }
 | 
						|
 | 
						|
  return -1;                 // Value not found!
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 50%
 | 
						|
void TList_sheet::do_output(CheckTime t)
 | 
						|
{
 | 
						|
  if (_row < 0 || t == FINAL_CHECK) 
 | 
						|
    return;
 | 
						|
  
 | 
						|
  _out_id.restart();
 | 
						|
  TToken_string& rowsel = _sheet->row(_row);
 | 
						|
  rowsel.restart();
 | 
						|
  for (const char* fld = _out_id.get(); fld; fld = _out_id.get())
 | 
						|
  {
 | 
						|
    const short id = _fld->atodlg(fld);
 | 
						|
    TMask_field& f = field(id);
 | 
						|
    const char* val = rowsel.get();
 | 
						|
    if (t != STARTING_CHECK || f.field() == NULL)
 | 
						|
    {
 | 
						|
      f.set(val);
 | 
						|
      if (field().dlg() != id)
 | 
						|
        f.on_hit();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
KEY TList_sheet::run()
 | 
						|
{
 | 
						|
  _row = do_input();
 | 
						|
 | 
						|
  _sheet->select(_row);
 | 
						|
 | 
						|
  const KEY k = _sheet->run();
 | 
						|
 | 
						|
  switch (k)
 | 
						|
  {
 | 
						|
  case K_ENTER:
 | 
						|
    _row = (int)_sheet->selected();
 | 
						|
    do_output();
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
bool TList_sheet::check(CheckTime t)
 | 
						|
{
 | 
						|
  const bool passed = (_row = do_input()) != -1;
 | 
						|
  if (passed) do_output(t);
 | 
						|
  return passed;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TBrowse
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TBrowse::TBrowse(TEdit_field* f, TRelation* r, int key, const char* filter)
 | 
						|
: _relation(r), _cursor(new TCursor (r, filter, key)),
 | 
						|
  _fld(f), _filter(filter), _secondary(FALSE), _checked(FALSE)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TBrowse::TBrowse(TEdit_field* f, TCursor* c)
 | 
						|
: _relation(NULL), _cursor(c), _fld(f), _secondary(FALSE), _checked(FALSE)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TBrowse::~TBrowse()
 | 
						|
{
 | 
						|
  if (_relation)
 | 
						|
  {
 | 
						|
    delete _relation;
 | 
						|
    delete _cursor;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TBrowse::parse_display(TScanner& scanner)
 | 
						|
{              
 | 
						|
  const char* s;
 | 
						|
  s = scanner.string();
 | 
						|
  _head.add(s);
 | 
						|
  s = scanner.line();
 | 
						|
  _items.add(s);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  const char* s = scanner.pop();
 | 
						|
  _inp_fn.add(s);
 | 
						|
 | 
						|
  s = scanner.pop();
 | 
						|
  if (*s == '"')        // Constant string
 | 
						|
  {
 | 
						|
    scanner.push();
 | 
						|
    TString& str = scanner.line();
 | 
						|
    _inp_id.add(str);
 | 
						|
 | 
						|
    if (_cursor->file().num() == LF_GOLEM)       // GOLEM 2 detected!
 | 
						|
    {               
 | 
						|
      str.strip("\"");
 | 
						|
      _insert = "G";
 | 
						|
      _insert << str;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else            // Field on the mask
 | 
						|
  {
 | 
						|
    TString80 str(s);
 | 
						|
    if (scanner.popkey() == "SE") str << '@';       // Special FILTERing field
 | 
						|
    else scanner.push();
 | 
						|
    _inp_id.add(str);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::parse_output(TScanner& scanner)
 | 
						|
{
 | 
						|
  const char* s = scanner.pop();
 | 
						|
#ifdef DBG      
 | 
						|
  field().atodlg(s);
 | 
						|
#endif  
 | 
						|
  _out_id.add(s);
 | 
						|
  s = scanner.pop();
 | 
						|
  _out_fn.add(s);  
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TBrowse::parse_copy(const TString& what, const TBrowse& b)
 | 
						|
{
 | 
						|
  const bool all = what == "AL";
 | 
						|
  if (all || what == "US")
 | 
						|
  {
 | 
						|
    set_insert(b.get_insert());
 | 
						|
    _filter = b.get_filter();
 | 
						|
    if (field()._warning.empty()) 
 | 
						|
      field()._warning = b.field()._warning;
 | 
						|
    if (!all) return TRUE;
 | 
						|
  }
 | 
						|
  if (all || what == "IN")
 | 
						|
  {
 | 
						|
    _inp_id = b._inp_id;
 | 
						|
    _inp_fn = b._inp_fn;
 | 
						|
    if (!all) return TRUE;
 | 
						|
  }
 | 
						|
  if (all || what == "DI")
 | 
						|
  {
 | 
						|
    _head = b._head;
 | 
						|
    _items = b._items;
 | 
						|
    if (!all) return TRUE;
 | 
						|
  }
 | 
						|
  if (all || what == "OU")
 | 
						|
  {
 | 
						|
    _out_id = b._out_id;
 | 
						|
    _out_fn = b._out_fn;
 | 
						|
    _secondary = b.field().has_check();
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::parse_join(TScanner& scanner)
 | 
						|
{
 | 
						|
  TString80 j(scanner.pop());             // File or table
 | 
						|
 | 
						|
  CHECKS(_relation, "Can't join to NULL relation ", (const char*)j);
 | 
						|
 | 
						|
  int to;
 | 
						|
  if (scanner.popkey() == "TO")         // TO keyword
 | 
						|
  {
 | 
						|
    const char* t = scanner.pop();
 | 
						|
    to = name2log(t);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    to = 0;                  // _relation->lfile()->num();
 | 
						|
    scanner.push();
 | 
						|
  }
 | 
						|
 | 
						|
  int key = 1;
 | 
						|
  if (scanner.popkey() == "KE")
 | 
						|
    key = scanner.integer();
 | 
						|
  else scanner.push();
 | 
						|
 | 
						|
  byte alias = 0;
 | 
						|
  if (scanner.popkey() == "AL")
 | 
						|
    alias = scanner.integer();
 | 
						|
  else scanner.push();
 | 
						|
 | 
						|
  TToken_string exp(80);
 | 
						|
  if (scanner.pop() == "INTO")
 | 
						|
  {
 | 
						|
    const char* r = scanner.pop();
 | 
						|
    while (strchr(r, '=') != NULL)
 | 
						|
    {
 | 
						|
      exp.add(r);
 | 
						|
      r = scanner.pop();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  scanner.push();
 | 
						|
 | 
						|
#ifdef DBG      
 | 
						|
  if (exp.empty()) yesnofatal_box("JOIN senza espressioni INTO");
 | 
						|
#endif  
 | 
						|
 | 
						|
  if (isdigit(j[0]))
 | 
						|
    _relation->add(atoi(j), exp, key, to, alias);   // join file
 | 
						|
  else
 | 
						|
  {
 | 
						|
#ifdef DBG      
 | 
						|
    if (j.len() > 4)
 | 
						|
      yesnofatal_box("'%s' non e' una tabella valida: %d", (const char*)j);
 | 
						|
    else  
 | 
						|
#endif          
 | 
						|
      _relation->add(j, exp, key, to, alias);      // join table
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::parse_insert(TScanner& scanner)
 | 
						|
{
 | 
						|
  const TString& key = scanner.popkey();
 | 
						|
  _insert.cut(0);
 | 
						|
  if (key != "NO")
 | 
						|
  {
 | 
						|
    _insert << key[0] << scanner.line();
 | 
						|
    _insert.trim();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TMask_field& TBrowse::field(short n) const
 | 
						|
{ return _fld->mask().field(n); }
 | 
						|
 | 
						|
 | 
						|
// Ritorna il numero di inputs senza contare quelli che funzionano solo da filtro
 | 
						|
int TBrowse::inputs()
 | 
						|
{
 | 
						|
  int inp = 0;
 | 
						|
  for (const char* fld = _inp_id.get(0); fld; fld = _inp_id.get())
 | 
						|
  {                                             
 | 
						|
    
 | 
						|
    if (*fld != '"' && strchr(fld, '@') == NULL && field(atoi(fld)).is_edit())
 | 
						|
      inp++;
 | 
						|
  }
 | 
						|
  return inp;    
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Ritorna il numero di campi non vuoti e non filtrati
 | 
						|
//
 | 
						|
// @rdesc Numero di campi non vuoti e non filtrati
 | 
						|
int TBrowse::do_input(
 | 
						|
  bool filter) // @parm ??
 | 
						|
 | 
						|
  // @comm Questa funzione serve ai TCursor_sheet
 | 
						|
{
 | 
						|
  int ne = 0;
 | 
						|
  if (_inp_id.empty()) return ne;
 | 
						|
 | 
						|
  TRectype& cur = _cursor->curr();
 | 
						|
 | 
						|
  cur.zero();
 | 
						|
  TRectype filtrec(cur);
 | 
						|
 | 
						|
  _inp_id.restart();
 | 
						|
  _inp_fn.restart();
 | 
						|
 | 
						|
  TString256 val;                  // Value to output
 | 
						|
  bool tofilter;
 | 
						|
 | 
						|
  for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get())
 | 
						|
  {
 | 
						|
    if (*fld == '"')
 | 
						|
    {
 | 
						|
      val = (fld+1);
 | 
						|
      if (val.not_empty()) val.rtrim(1);
 | 
						|
      tofilter = filter;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      const short id  = _fld->atodlg(fld);
 | 
						|
      const bool filter_flag = strchr(fld, '@') != NULL;
 | 
						|
      tofilter = filter && filter_flag;
 | 
						|
      val = field(id).get();
 | 
						|
      
 | 
						|
      const TMask_field& f = field(id);
 | 
						|
      if (f.class_id() == CLASS_DATE_FIELD && f.right_justified())
 | 
						|
      {
 | 
						|
        const TDate d(val);
 | 
						|
        val = d.string(ANSI);
 | 
						|
      }
 | 
						|
      
 | 
						|
      if (f.is_edit() && val.not_empty() && !filter_flag) 
 | 
						|
        ne++;          // Increment not empty fields count
 | 
						|
    }
 | 
						|
 | 
						|
    TFieldref fldref(_inp_fn.get(), 0); // Output field
 | 
						|
    fldref.write(val, _cursor->relation());
 | 
						|
    if (tofilter)
 | 
						|
    {
 | 
						|
      if (val.empty()) val.fill('~', fldref.len(cur));
 | 
						|
      fldref.write(val, filtrec);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!filter) return ne;
 | 
						|
 | 
						|
  TString work(_filter.size());
 | 
						|
  for (int i = 0; _filter[i]; i++)
 | 
						|
  {
 | 
						|
    if (_filter[i] == '"')
 | 
						|
    { 
 | 
						|
      do
 | 
						|
      {
 | 
						|
        work << _filter[i++];
 | 
						|
      } while (_filter[i] && _filter[i] != '"');
 | 
						|
      work << '"';
 | 
						|
      if (!_filter[i]) break;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if (_filter[i] == '#')
 | 
						|
      {
 | 
						|
        work << '"' << field(atoi(&_filter[++i])).get() << '"';
 | 
						|
        while (isspace(_filter[i])) i++;
 | 
						|
        while (isdigit(_filter[i])) i++;
 | 
						|
        i--;
 | 
						|
      }
 | 
						|
      else work << _filter[i];
 | 
						|
  }
 | 
						|
 | 
						|
  _cursor->setfilter(work);
 | 
						|
  _cursor->setregion(filtrec, filtrec);
 | 
						|
 | 
						|
  return ne;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::do_output(CheckTime t)
 | 
						|
{   
 | 
						|
  if (t == FINAL_CHECK) 
 | 
						|
    return;
 | 
						|
 | 
						|
  TString sum;
 | 
						|
  TToken_string flds(24, '+');
 | 
						|
 | 
						|
  _out_fn.restart();
 | 
						|
  for (const char* fld = _out_id.get(0); fld && *fld; fld = _out_id.get())
 | 
						|
  {
 | 
						|
    const short id = field().atodlg(fld);
 | 
						|
    TMask_field& f = field(id);
 | 
						|
 | 
						|
    flds = _out_fn.get();
 | 
						|
    if (t != STARTING_CHECK || f.field() == NULL || f.mask().mode() == MODE_INS)
 | 
						|
    {
 | 
						|
      sum.cut(0);
 | 
						|
      for(const char* fr = flds.get(0); fr; fr = flds.get())
 | 
						|
      {  
 | 
						|
        if (*fr == '"')
 | 
						|
        {       
 | 
						|
          sum << (fr+1);
 | 
						|
          sum.rtrim(1);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          const TFieldref fld(fr, 0);
 | 
						|
          sum << fld.read(_cursor->relation());
 | 
						|
        }  
 | 
						|
      }
 | 
						|
 | 
						|
      f.set(sum);
 | 
						|
      if (field().dlg() != id)
 | 
						|
        f.on_hit();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::do_clear()
 | 
						|
{                  
 | 
						|
  for (TString16 fld = _out_id.get(0); fld.not_empty(); fld = _out_id.get())
 | 
						|
  {
 | 
						|
    TMask_field& f = field(atoi(fld));
 | 
						|
    if (f.field() == NULL && _inp_id.get_pos(fld) < 0) 
 | 
						|
      f.reset();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TBrowse::do_insert()
 | 
						|
{
 | 
						|
  bool ok = FALSE;
 | 
						|
  TString80 app;
 | 
						|
 | 
						|
  if (_insert[0] == 'M')
 | 
						|
  {
 | 
						|
    TString80 nm(_insert.mid(1));
 | 
						|
    if (nm.compare("batb", 4, TRUE) == 0)    // Programma gestione tabelle
 | 
						|
      app = format("ba3 -0 %s", (const char*)nm.mid(4));
 | 
						|
    // Obbligatorio usare la format globale
 | 
						|
    else                              // Programma generico di browse/edit
 | 
						|
      app = format("ba3 -3 %s %d", (const char*)nm, _cursor->file().num());
 | 
						|
    // Obbligatorio usare la format globale
 | 
						|
  }
 | 
						|
  else if (_insert[0] == 'G')
 | 
						|
  { 
 | 
						|
    TGolem golem(&_insert[1], atol(field().get()));
 | 
						|
    const bool ok = golem.edit();
 | 
						|
    return ok ? TRUE : error_box("Impossibile modificare l'oggetto");
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    app = &_insert[1];
 | 
						|
  }
 | 
						|
  if (app.find('#') != -1)
 | 
						|
  {
 | 
						|
    TString80 w(app);
 | 
						|
    app = "";
 | 
						|
    for (const char* f = w; *f; f++)
 | 
						|
    {
 | 
						|
      if (*f == '#') 
 | 
						|
      {
 | 
						|
        const int id = atoi(++f);
 | 
						|
        app << _fld->mask().get(id);
 | 
						|
        while (isspace(*f)) ++f;
 | 
						|
        while (isdigit(*f)) ++f; 
 | 
						|
        if (*f)
 | 
						|
          app << ' ' << *f;
 | 
						|
        else 
 | 
						|
          break;
 | 
						|
      }            
 | 
						|
      else
 | 
						|
        app << *f;
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  TMailbox mail;
 | 
						|
  TMessage msg(app, MSG_AI, "");
 | 
						|
  mail.send(msg);
 | 
						|
 | 
						|
  TExternal_app a(app);
 | 
						|
  a.run();
 | 
						|
 | 
						|
  if (mail.check())
 | 
						|
  {
 | 
						|
    TMessage* rcv = mail.next_s(MSG_AI);
 | 
						|
    if (rcv != NULL) _rec = atoi(rcv->body());
 | 
						|
    if (_rec > 0)
 | 
						|
    {
 | 
						|
      _cursor->file().readat(_rec);
 | 
						|
      ok = _cursor->ok();
 | 
						|
      if (ok) do_output();
 | 
						|
#ifdef DBG      
 | 
						|
      else yesnofatal_box("Selezione da programma esterno errata");
 | 
						|
#endif      
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TToken_string& TBrowse::create_siblings(TToken_string& siblings)
 | 
						|
{
 | 
						|
  const TMask& mask = field().mask();
 | 
						|
  siblings = "";                      // Azzera la lista dei campi associati
 | 
						|
  
 | 
						|
  //  if (!mask.is_running()) return siblings;
 | 
						|
  
 | 
						|
  TBit_array key(4);                  // Elenco delle chiavi gia' utilizzate
 | 
						|
  key.set(_cursor->key());
 | 
						|
  
 | 
						|
  // Scorre la lista dei campi di output
 | 
						|
  int n = 0;  
 | 
						|
  for (const char* i = _out_id.get(0); i; i = _out_id.get(), n++)
 | 
						|
  {
 | 
						|
    const short id = _fld->atodlg(i);
 | 
						|
    const TMask_field& f = mask.field(id);
 | 
						|
    if (!f.shown() || !f.is_edit())  // Scarta i campi non editabili
 | 
						|
      continue;
 | 
						|
    const TEdit_field& e = (const TEdit_field&)f;
 | 
						|
    const TBrowse* b = e.browse();
 | 
						|
    if (b == NULL) 
 | 
						|
      continue;                       // Scarta i campi senza ricerca
 | 
						|
    
 | 
						|
    const TCursor* c = b->cursor();  
 | 
						|
    
 | 
						|
    // Considera ricerche sullo stesso file ma con chiave diversa
 | 
						|
    if (c->file().num() == _cursor->file().num() && 
 | 
						|
        (key[c->key()] == FALSE || id == _fld->dlg()))      
 | 
						|
    {
 | 
						|
      TString16 fn(_out_fn.get(n));           // Legge nome del campo su file          
 | 
						|
      int pos = _items.get_pos(fn);           // Determina header corrispondente
 | 
						|
      if (pos < 0)                            // Se non lo trova identico ...
 | 
						|
      {
 | 
						|
        const int q = fn.find('[');
 | 
						|
        if (q > 0)
 | 
						|
        {
 | 
						|
          fn.cut(q);
 | 
						|
          pos = _items.get_pos(fn);           // ... ritenta senza parentesi
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (pos >= 0)
 | 
						|
      {
 | 
						|
        siblings.add(id);
 | 
						|
        const char* h = _head.get(pos); 
 | 
						|
        siblings.add(h);
 | 
						|
        const int et = siblings.find('@');
 | 
						|
        if (et > 0) siblings.cut(et);
 | 
						|
        key.set(c->key());                    // Marca la chiave come usata
 | 
						|
      }  
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  return siblings;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
KEY TBrowse::run()
 | 
						|
{
 | 
						|
  do_input(TRUE);
 | 
						|
  _cursor->read(_isgteq);
 | 
						|
 | 
						|
  const TLocalisamfile& f = _cursor->file();
 | 
						|
  TString80 caption(prefix().description(f.name()));
 | 
						|
  if (!isalnum(caption[0])) 
 | 
						|
    caption = "Selezione";
 | 
						|
  
 | 
						|
  KEY k = K_ESC;
 | 
						|
  long selected = 0;
 | 
						|
 | 
						|
  TToken_string siblings; 
 | 
						|
  create_siblings(siblings);                            
 | 
						|
  
 | 
						|
{
 | 
						|
  TToken_string* sib = siblings.empty() ? NULL : &siblings;
 | 
						|
  byte buttons = 0;
 | 
						|
  if (_insert.not_empty())
 | 
						|
  {   
 | 
						|
    buttons = 1;      // Mette il bottone di gestione, a meno che ...   
 | 
						|
    
 | 
						|
    if (_insert[0] == 'G')
 | 
						|
    {
 | 
						|
      buttons |= 2;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {         
 | 
						|
      const TString& maskname = _fld->mask().source_file();
 | 
						|
      if (maskname.compare("batb", 4, TRUE) == 0 && _fld->in_key(0))
 | 
						|
      {
 | 
						|
        const char* tabname = _cursor->file().name();
 | 
						|
        if (maskname.mid(4, 3).compare(tabname, 3, TRUE) == 0) 
 | 
						|
          buttons = 0;
 | 
						|
      }
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  
 | 
						|
  TBrowse_sheet s(_cursor, _items, caption, _head, buttons, _fld, sib);
 | 
						|
  k = s.run();
 | 
						|
  selected = s.selected();
 | 
						|
}
 | 
						|
 | 
						|
switch (k)
 | 
						|
{
 | 
						|
 case K_INS:    
 | 
						|
  if (_insert[0] == 'G')
 | 
						|
    field().set(format("%ld", selected+1));
 | 
						|
  k = do_insert() ? K_ENTER : K_ESC;
 | 
						|
  break;
 | 
						|
 case K_CTRL+'N':
 | 
						|
{
 | 
						|
  TGolem gol(&_insert[1], 0);
 | 
						|
  if (gol.import())
 | 
						|
    field().set(format("%ld", gol.id()));
 | 
						|
}
 | 
						|
k = K_ENTER;
 | 
						|
break;
 | 
						|
 case K_ENTER:
 | 
						|
 *_cursor = selected;
 | 
						|
 do_output();
 | 
						|
 break;
 | 
						|
default:
 | 
						|
if (k >= K_CTRL)
 | 
						|
{
 | 
						|
  const TMask& m = _fld->mask();
 | 
						|
  const short id = siblings.get_int((k - K_CTRL) << 1);
 | 
						|
  TEdit_field& ef = m.efield(id);
 | 
						|
  ef.set_focus();
 | 
						|
  k = K_F9;
 | 
						|
  if (m.is_running())
 | 
						|
    ef.send_key(k, 0);
 | 
						|
}
 | 
						|
break;
 | 
						|
}
 | 
						|
 | 
						|
return k;
 | 
						|
}
 | 
						|
 | 
						|
bool TBrowse::check(CheckTime t)
 | 
						|
{
 | 
						|
  bool passed = TRUE;
 | 
						|
 | 
						|
  if (_secondary == TRUE && t != RUNNING_CHECK)
 | 
						|
    return TRUE;
 | 
						|
 | 
						|
  if (_fld->check_type() != CHECK_NONE)
 | 
						|
  {
 | 
						|
    const TMaskmode mode = (TMaskmode)field().mask().mode();
 | 
						|
 | 
						|
    CheckType chk = _fld->check_type();
 | 
						|
    const int ne = do_input(TRUE);
 | 
						|
    if (t == STARTING_CHECK || mode == MODE_QUERY) chk = CHECK_NORMAL;
 | 
						|
    if (ne || chk == CHECK_REQUIRED)
 | 
						|
    {
 | 
						|
      _cursor->setkey();
 | 
						|
      _cursor->file().read(_isequal);
 | 
						|
      passed = _cursor->ok();
 | 
						|
 | 
						|
      if (t != FINAL_CHECK)
 | 
						|
      {
 | 
						|
        if (passed)
 | 
						|
        {
 | 
						|
          _cursor->repos();
 | 
						|
          do_output(t);
 | 
						|
        }
 | 
						|
        else 
 | 
						|
        {
 | 
						|
          do_clear();
 | 
						|
          if (!_fld->mask().query_mode() && _fld->check_enabled())
 | 
						|
            _fld->set_dirty(3);
 | 
						|
        }  
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
      if (t != FINAL_CHECK) do_clear();
 | 
						|
  }
 | 
						|
  return passed;
 | 
						|
}
 | 
						|
 | 
						|
bool TBrowse::empty_check()
 | 
						|
{
 | 
						|
  if ( field().mask().query_mode() || _fld->check_type() == CHECK_NONE ||
 | 
						|
      _fld->check_type() == CHECK_NORMAL)
 | 
						|
    return TRUE;
 | 
						|
  else
 | 
						|
    return do_input() > 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TEdit_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TEdit_field::TEdit_field(TMask* mask)
 | 
						|
: TMask_field(mask), _browse(NULL), _sheet(NULL),
 | 
						|
  _buttonwin(NULL_WIN), _check(CHECK_NONE), _check_enabled(FALSE),
 | 
						|
  _forced(FALSE)
 | 
						|
{}
 | 
						|
 | 
						|
TEdit_field::~TEdit_field()
 | 
						|
{
 | 
						|
  if (_browse) delete _browse; else
 | 
						|
    if (_sheet) delete _sheet;
 | 
						|
}
 | 
						|
 | 
						|
word TEdit_field::class_id() const
 | 
						|
{ return CLASS_EDIT_FIELD; }
 | 
						|
 | 
						|
 | 
						|
void TEdit_field::enable(bool on)
 | 
						|
{
 | 
						|
  TMask_field::enable(on);
 | 
						|
  if (_buttonwin != NULL_WIN)
 | 
						|
    xvt_vobj_set_visible(_buttonwin, on && check_enabled() && shown());
 | 
						|
}
 | 
						|
 | 
						|
void TEdit_field::show(bool on)
 | 
						|
{
 | 
						|
  TMask_field::show(on);
 | 
						|
  if (_buttonwin != NULL_WIN)
 | 
						|
    xvt_vobj_set_visible(_buttonwin, on && check_enabled() && enabled());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TEdit_field::parse_head(TScanner& scanner)
 | 
						|
{
 | 
						|
  _size  = scanner.integer();
 | 
						|
#ifdef DBG  
 | 
						|
  if (_size < 1)
 | 
						|
  {
 | 
						|
    _size = 8;
 | 
						|
    yesnofatal_box("Il campo %d ha dimensione nulla (uso %d)", dlg(), _size);
 | 
						|
  }
 | 
						|
#endif
 | 
						|
  _width = scanner.integer();
 | 
						|
  if (_width == 0) _width = _size;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const TBrowse* TEdit_field::get_browse(TScanner& scanner) const
 | 
						|
{
 | 
						|
  const int id = scanner.integer();
 | 
						|
  const TEdit_field& f = mask().efield(id);
 | 
						|
  const TBrowse* b = (const TBrowse*)f.browse();
 | 
						|
#ifdef DBG    
 | 
						|
  if (b == NULL)
 | 
						|
    yesnofatal_box("La USE del campo %d e' nulla e non puo' essere copiata nel campo %d", id, dlg());
 | 
						|
#endif    
 | 
						|
  return b;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TEdit_field::parse_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  if (scanner.key() == "PI")            // PICTURE
 | 
						|
  {
 | 
						|
    _picture = scanner.string();
 | 
						|
#ifdef DBG    
 | 
						|
    if (_picture == "." && _size > 9 && _size != 15) 
 | 
						|
      ::warning_box("Guy propone una dimensione di 15 per il campo %d: %s\nMa probabilmente ha toppato ...", 
 | 
						|
                    dlg(), (const char*)_prompt);
 | 
						|
#endif    
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "CH")
 | 
						|
  {
 | 
						|
    scanner.pop();
 | 
						|
    if (scanner.key() == "NO") _check = CHECK_NORMAL;
 | 
						|
    else if (scanner.key() == "RE") _check = CHECK_REQUIRED;
 | 
						|
    else if (scanner.key() == "FO") {_check = CHECK_REQUIRED; _forced = TRUE;}
 | 
						|
    else _check = CHECK_NONE;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "US")            // USE
 | 
						|
  {
 | 
						|
#ifdef DBG  
 | 
						|
    if (_browse != NULL)
 | 
						|
      return yesnofatal_box("USE duplicata nel campo %d", dlg());
 | 
						|
#endif
 | 
						|
    
 | 
						|
    int key = 1;
 | 
						|
    TRelation* r;
 | 
						|
 | 
						|
    const int logicnum = scanner.integer();
 | 
						|
    TString16 tabmaskname;
 | 
						|
 | 
						|
    if (logicnum > 0)
 | 
						|
      r = new TRelation(logicnum);
 | 
						|
    else
 | 
						|
    {
 | 
						|
      tabmaskname  = scanner.pop();
 | 
						|
#ifdef DBG  
 | 
						|
      if (tabmaskname.len() > 4)
 | 
						|
        return yesnofatal_box("'%s' non e' una tabella valida: %d",
 | 
						|
                              (const char*)tabmaskname, dlg());
 | 
						|
#endif                    
 | 
						|
      r = new TRelation(tabmaskname);
 | 
						|
    }
 | 
						|
 | 
						|
    if (scanner.popkey() == "KE")
 | 
						|
    {
 | 
						|
      key = scanner.integer();
 | 
						|
#ifdef DBG  
 | 
						|
      if (key < 1 || key > 15)
 | 
						|
      {
 | 
						|
        yesnofatal_box("Chiave %d non valida nella USE del campo %d", key, dlg());
 | 
						|
        key = 1;
 | 
						|
      }
 | 
						|
#endif      
 | 
						|
    }
 | 
						|
    else scanner.push();
 | 
						|
 | 
						|
    const char* filter = "";
 | 
						|
    if (scanner.popkey() == "SE")
 | 
						|
      filter = (const char*)scanner.line();
 | 
						|
    else
 | 
						|
      scanner.push();
 | 
						|
 | 
						|
    _browse = new TBrowse(this, r, key, filter);
 | 
						|
 | 
						|
    if (tabmaskname.not_empty())
 | 
						|
    {
 | 
						|
      tabmaskname.insert("MBATB", 0);
 | 
						|
      _browse->set_insert(tabmaskname);
 | 
						|
    }
 | 
						|
 | 
						|
    _check_enabled = TRUE;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "CO")                    // Copyuse
 | 
						|
  {
 | 
						|
    const TString16 what(scanner.popkey());
 | 
						|
 | 
						|
    const TBrowse* b = get_browse(scanner);
 | 
						|
    if (b == NULL) return FALSE;
 | 
						|
 | 
						|
    if (what == "US" || what == "AL")
 | 
						|
      _browse = new TBrowse(this, b->cursor());
 | 
						|
 | 
						|
    if (_browse) 
 | 
						|
    {
 | 
						|
      _check_enabled = TRUE;
 | 
						|
      return _browse->parse_copy(what, *b);
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef DBG
 | 
						|
    return yesnofatal_box("Impossibile COPY senza USE nel campo %d", dlg());
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "JO")
 | 
						|
  {
 | 
						|
#ifdef DBG      
 | 
						|
    if(!_browse) return yesnofatal_box("JOIN senza USE nel campo %d", dlg());
 | 
						|
#endif
 | 
						|
    _browse->parse_join(scanner);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "SH")            // SHEET
 | 
						|
  {
 | 
						|
#ifdef DBG    
 | 
						|
    if (_sheet) return yesnofatal_box("SHEET duplicato nel campo %d", dlg());
 | 
						|
#endif
 | 
						|
    _sheet = new TList_sheet(this, _prompt, scanner.string()); 
 | 
						|
    _check_enabled = TRUE;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "IT")            // ITEM
 | 
						|
  {
 | 
						|
#ifdef DBG    
 | 
						|
    if (_sheet == NULL) return yesnofatal_box("ITEM senza SHEET nel campo %d", dlg());
 | 
						|
#endif    
 | 
						|
    _sheet->read_item(scanner);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "IN")
 | 
						|
  {
 | 
						|
    if (_browse) _browse->parse_input(scanner); else
 | 
						|
      if (_sheet) _sheet->parse_input(scanner);
 | 
						|
#ifdef DBG    
 | 
						|
      else yesnofatal_box("INPUT senza USE o SHEET nel campo %d", dlg());
 | 
						|
#endif      
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "DI")
 | 
						|
  {
 | 
						|
#ifdef DBG    
 | 
						|
    if(!_browse) return yesnofatal_box("DISPLAY senza USE nel campo %d", dlg());
 | 
						|
#endif
 | 
						|
    _browse->parse_display(scanner);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "OU")
 | 
						|
  {
 | 
						|
    if (_browse) _browse->parse_output(scanner);
 | 
						|
    else if (_sheet)  _sheet->parse_output(scanner);
 | 
						|
#ifdef DBG    
 | 
						|
    else return yesnofatal_box("OUTPUT senza USE nel campo %d", dlg());
 | 
						|
#endif    
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "AD")
 | 
						|
  {
 | 
						|
#ifdef DBG    
 | 
						|
    if(!_browse) return yesnofatal_box("ADD senza USE nel campo %d", dlg());
 | 
						|
#endif    
 | 
						|
    _browse->parse_insert(scanner);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "ME")
 | 
						|
  {                
 | 
						|
    TFixed_string l(scanner.line().strip_spaces());
 | 
						|
    int m = 0;
 | 
						|
    if (l[0] == '0')
 | 
						|
    {            
 | 
						|
      l.ltrim(1);
 | 
						|
      l.ltrim();    
 | 
						|
      m = 1;
 | 
						|
    }                      
 | 
						|
    if (_message.objptr(m) == 0)
 | 
						|
      _message.add(new TToken_string(64), m);
 | 
						|
    TToken_string& ts = (TToken_string&)_message[m];
 | 
						|
    ts.add(l);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TMask_field::parse_item(scanner);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TEdit_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  const int len = create_prompt(parent);
 | 
						|
 | 
						|
  long bandiere = _flags.rightjust ? CTL_FLAG_RIGHT_JUST : CTL_FLAG_LEFT_JUST;
 | 
						|
  if (_flags.uppercase) bandiere |= CTL_FLAG_MAC_GENEVA9;
 | 
						|
  if (_flags.password) bandiere |= CTL_FLAG_MAC_MONACO9;
 | 
						|
  
 | 
						|
  _x += len;
 | 
						|
 | 
						|
#if XVTWS == WMWS
 | 
						|
  const int delta = 2;
 | 
						|
#else
 | 
						|
  const int delta = 1;
 | 
						|
#endif
 | 
						|
 | 
						|
  wincreate(WC_EDIT, _width+delta, 1, _str, parent, bandiere);
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
  HWND hwnd = (HWND)xvt_vobj_get_attr(win(), ATTR_NATIVE_WINDOW);
 | 
						|
  SendMessage(hwnd, EM_LIMITTEXT, _size, 0L);    // Limita il testo
 | 
						|
#endif
 | 
						|
 | 
						|
  if (_browse || _sheet)
 | 
						|
  {
 | 
						|
    long flags = default_flags();
 | 
						|
    if (flags & CTL_FLAG_DISABLED)
 | 
						|
    {
 | 
						|
      flags &= ~CTL_FLAG_DISABLED;
 | 
						|
      flags |= CTL_FLAG_INVISIBLE;
 | 
						|
    }      
 | 
						|
    
 | 
						|
    TString16 ico("*");                      
 | 
						|
    if (_browse && _browse->get_insert()[0] == 'G')
 | 
						|
    {                        
 | 
						|
      const char* g = _browse->get_insert();
 | 
						|
      TGolem golem(g+1, 0);
 | 
						|
      ico.format("#%d", golem.icon());
 | 
						|
    }
 | 
						|
    _buttonwin = xvt_create_control(WC_PUSHBUTTON, _x+_width+delta, _y,
 | 
						|
                                    2, 1, ico, parent, flags, PTR_LONG(this), DLG_F9);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TEdit_field::set_back_color(COLOR c) const
 | 
						|
{         
 | 
						|
  if (_promptwin != NULL_WIN)
 | 
						|
    xvt_set_ctrl_back_color(_promptwin, c);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TEdit_field::destroy()
 | 
						|
{
 | 
						|
  if (_buttonwin)
 | 
						|
  { xvt_vobj_destroy(_buttonwin); _buttonwin = NULL_WIN; }
 | 
						|
  TMask_field::destroy();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TEdit_field::set_window_data(const char* data)
 | 
						|
{
 | 
						|
  TMask_field::set_window_data(format(data));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TEdit_field::set_field_data(const char* data)
 | 
						|
{ _str = data; }
 | 
						|
 | 
						|
const char* TEdit_field::get_field_data() const
 | 
						|
{ return _str; }
 | 
						|
 | 
						|
 | 
						|
const char* TEdit_field::format(const char* d) const
 | 
						|
{
 | 
						|
  fpark = d;
 | 
						|
  if (_flags.trim) fpark.trim();
 | 
						|
 | 
						|
  if (fpark.not_empty())
 | 
						|
  {            
 | 
						|
    int len = fpark.len();
 | 
						|
    if (len > _size)
 | 
						|
    {
 | 
						|
#ifdef DBG      
 | 
						|
      yesnofatal_box("Campo %d troppo lungo: %s > %d", dlg(), (const char*)fpark, _size);
 | 
						|
#endif      
 | 
						|
      fpark.cut(len = _size);
 | 
						|
    }
 | 
						|
 | 
						|
    if (len < _size)
 | 
						|
    {                  
 | 
						|
      if (_flags.zerofilled)
 | 
						|
      {
 | 
						|
        if (isdigit(fpark[0]) && real::is_real(fpark))
 | 
						|
          fpark.right_just(_size, '0');
 | 
						|
      }
 | 
						|
      else  
 | 
						|
        if (_flags.rightjust)
 | 
						|
          fpark.right_just(_size);
 | 
						|
    }      
 | 
						|
    
 | 
						|
    if (_flags.uppercase)
 | 
						|
      fpark.upper();
 | 
						|
    
 | 
						|
    for (int p = 0; fpark[p]; p++)
 | 
						|
      if (fpark[p] == '|') fpark[p] = '/';
 | 
						|
  }
 | 
						|
 | 
						|
  return fpark;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
const char* TEdit_field::picture_data(const char* data, bool video) const
 | 
						|
{
 | 
						|
  fpark = video ? data : format(data);
 | 
						|
  if (_flags.trim) fpark.trim();
 | 
						|
  return fpark;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Chiama l' eventuale funzione di validazione
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato dell funzione di validazione:
 | 
						|
//
 | 
						|
// @flag TRUE | Se la validata ha avuto successo
 | 
						|
// @flag FALSE | Se la validata no ha avuto successo
 | 
						|
bool TEdit_field::validate(
 | 
						|
  KEY k) // @parm Tasto da passare alla funzione di validazione
 | 
						|
{                 
 | 
						|
  return _validate_func < 0 ? TRUE : ::validate(_validate_func, *this, k, _validate_parms);
 | 
						|
}
 | 
						|
 | 
						|
// Certified 90%
 | 
						|
bool TEdit_field::on_hit()
 | 
						|
{
 | 
						|
  if (_validate_func >= 0 && 
 | 
						|
      (_validate_func == AUTOEXIT_FUNC || 
 | 
						|
       _validate_func == NUMCALC_FUNC ||
 | 
						|
       _validate_func == STRCALC_FUNC))
 | 
						|
  {
 | 
						|
    set(get());
 | 
						|
    bool ok = validate(is_edit() ? K_TAB : K_SPACE);     // Check validation expression
 | 
						|
    if (!ok) return FALSE;
 | 
						|
  }
 | 
						|
  if (_handler)
 | 
						|
  {
 | 
						|
    bool ok = _handler(*this, is_edit() ? K_TAB : K_SPACE);
 | 
						|
    if (!ok) return FALSE;
 | 
						|
  } 
 | 
						|
  if (_message.objptr(1) && get() == "") do_message(1);
 | 
						|
  else do_message(0);
 | 
						|
  return TRUE;
 | 
						|
} 
 | 
						|
 | 
						|
// @mfunc Mostra un messaggio di errore di default per il campo
 | 
						|
//
 | 
						|
// @rdesc Ritorna sempre FALSE
 | 
						|
bool TEdit_field::default_error_box() const
 | 
						|
 | 
						|
// @comm Se il campo non possiede un warning particolare chiama la <f error_box>
 | 
						|
//       indicando genericamente che il valore immesso non e' valido, altrimenti
 | 
						|
//       riporta il warning associato al campo
 | 
						|
{                 
 | 
						|
  if (_warning.empty()) 
 | 
						|
  {
 | 
						|
    const char* p = prompt();
 | 
						|
    if (isalnum(p[0]))
 | 
						|
      error_box("Valore non valido per %s: '%s'", p, (const char*)get());
 | 
						|
    else  
 | 
						|
      error_box("Valore non valido: '%s'", (const char*)get());
 | 
						|
  }    
 | 
						|
  else
 | 
						|
    error_box(_warning);
 | 
						|
  return FALSE;  
 | 
						|
}
 | 
						|
 | 
						|
bool TEdit_field::on_key(KEY key)
 | 
						|
{
 | 
						|
  switch(key)
 | 
						|
  {
 | 
						|
  case K_TAB:
 | 
						|
    if (_validate_func >= 0 && 
 | 
						|
        (_validate_func == AUTOEXIT_FUNC || 
 | 
						|
         _validate_func == NUMCALC_FUNC ||
 | 
						|
         _validate_func == STRCALC_FUNC))
 | 
						|
      set_focusdirty();            // Forza validate
 | 
						|
    if (to_check(K_TAB, TRUE))
 | 
						|
    {
 | 
						|
      set(get());
 | 
						|
      bool ok = validate(key);     // Check validation expression
 | 
						|
 | 
						|
      if (!ok)
 | 
						|
      {
 | 
						|
        if (_warning.not_empty()) 
 | 
						|
          error_box(_warning);
 | 
						|
        return FALSE;
 | 
						|
      }
 | 
						|
 | 
						|
      TMask& m = mask();
 | 
						|
      const bool query = m.query_mode();
 | 
						|
 | 
						|
      if (_sheet) ok = query || _sheet->check();  // Check consistency
 | 
						|
      else
 | 
						|
        if (_browse && check_enabled() && (!query || forced()) && _validate_func != 21) 
 | 
						|
          ok = _browse->check();
 | 
						|
      
 | 
						|
      if (!ok) return default_error_box();
 | 
						|
      
 | 
						|
      ok = on_hit();
 | 
						|
      if (!ok) return FALSE;
 | 
						|
 | 
						|
      if (query && required() && in_key(0))
 | 
						|
      {
 | 
						|
        const byte keys = m.num_keys();
 | 
						|
 | 
						|
        for (int i = 1; i <= keys; i++)
 | 
						|
          if (in_key(i) && m.key_valid(i))
 | 
						|
          {
 | 
						|
            for (int fld = m.get_key_field(i, TRUE); fld != -1; fld = m.get_key_field(i, FALSE))
 | 
						|
              m.field(fld).set_dirty(FALSE);
 | 
						|
            mask().stop_run(K_AUTO_ENTER);
 | 
						|
            break;
 | 
						|
          }
 | 
						|
      }
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case K_ENTER:
 | 
						|
    if (field() != NULL || mask().mode() == NO_MODE)
 | 
						|
    {
 | 
						|
      if (focusdirty()) set(get());
 | 
						|
 | 
						|
      bool ok = validate(K_ENTER);                           // Check validation expression
 | 
						|
      if (!ok)
 | 
						|
      {
 | 
						|
        if (_warning.not_empty()) 
 | 
						|
          error_box(_warning);
 | 
						|
        return FALSE;
 | 
						|
      }
 | 
						|
      
 | 
						|
      const bool query = mask().query_mode();
 | 
						|
 | 
						|
      // check consistency
 | 
						|
      if (_sheet) 
 | 
						|
        ok = query || _sheet->check(FINAL_CHECK);  
 | 
						|
      else 
 | 
						|
      {
 | 
						|
        ok = query || !(check_type() == CHECK_REQUIRED && get().empty());
 | 
						|
        if (_browse && ok &&
 | 
						|
            check_enabled() &&
 | 
						|
            _validate_func != 21 && // 21 = NOT_EMPTY_CHECK_FIELD
 | 
						|
            (!query || forced()))
 | 
						|
        {
 | 
						|
          if (dirty()) ok = _browse->check(FINAL_CHECK);     // Check consistency
 | 
						|
          else ok = _browse->empty_check();
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (!ok)
 | 
						|
        return default_error_box();
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case K_F9:
 | 
						|
    if (check_enabled())
 | 
						|
    {  
 | 
						|
      enable_check(FALSE);
 | 
						|
      if (dirty()) set(get());
 | 
						|
      KEY k = K_ESC;
 | 
						|
      if (_browse) k = _browse->run();
 | 
						|
      else 
 | 
						|
        if (_sheet) k = _sheet->run();
 | 
						|
        else beep();
 | 
						|
      if (k != K_F9) set_focus();
 | 
						|
      enable_check(TRUE);
 | 
						|
      if (k == K_ENTER)
 | 
						|
      {
 | 
						|
        set_dirty();
 | 
						|
        if (mask().is_running())   
 | 
						|
          send_key(K_TAB, 0);
 | 
						|
        else
 | 
						|
          on_hit();
 | 
						|
        return TRUE;
 | 
						|
      } 
 | 
						|
      else 
 | 
						|
        return FALSE;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return TMask_field::on_key(key);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TEdit_field::has_check() const
 | 
						|
{
 | 
						|
  if (_browse) return check_type() != CHECK_NONE;
 | 
						|
  return _sheet != NULL;
 | 
						|
}
 | 
						|
 | 
						|
bool TEdit_field::check(CheckTime t)
 | 
						|
{                
 | 
						|
  bool ok = TRUE;
 | 
						|
  if (check_enabled() || (t == STARTING_CHECK && shown()))
 | 
						|
  {
 | 
						|
    if (_browse) ok = (_validate_func == 21) || _browse->check(t); 
 | 
						|
    else if (_sheet) ok = _sheet->check(t);
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Permette di abilitare/disabilitare un check di un campo
 | 
						|
void TEdit_field::enable_check(
 | 
						|
  bool on) // @parm Operazione da svolgere
 | 
						|
  //
 | 
						|
  // @flag TRUE | Abilita il check del campo (default)
 | 
						|
  // @flag FALSE | Disabilita il check del campo
 | 
						|
{
 | 
						|
  _check_enabled = on;
 | 
						|
  if (_buttonwin != NULL_WIN)
 | 
						|
    xvt_vobj_set_visible(_buttonwin, on);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Boolean_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
 | 
						|
TBoolean_field::TBoolean_field(TMask* m)
 | 
						|
: TMask_field(m), _on(FALSE)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
word TBoolean_field::class_id() const
 | 
						|
{ return CLASS_BOOLEAN_FIELD; }
 | 
						|
 | 
						|
 | 
						|
void TBoolean_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  wincreate(WC_CHECKBOX, _prompt.len()+3, 1, _prompt, parent, 0);
 | 
						|
}
 | 
						|
 | 
						|
void TBoolean_field::set_back_color(COLOR c) const
 | 
						|
{
 | 
						|
  xvt_set_ctrl_back_color(win(), c);
 | 
						|
}
 | 
						|
 | 
						|
const char* TBoolean_field::get_window_data() const
 | 
						|
{
 | 
						|
  CHECK(win(), "Control window not initialized");
 | 
						|
  fpark[0] = xvt_get_checked_state(win()) ? 'X' : ' ';
 | 
						|
  fpark[1] = '\0';
 | 
						|
  return fpark;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBoolean_field::set_window_data(const char* data)
 | 
						|
{
 | 
						|
  CHECK(win(), "Control window not initialized");
 | 
						|
 | 
						|
  if (data == NULL) data = "";
 | 
						|
  const bool b = toupper(*data) == 'X';
 | 
						|
  xvt_check_box(win(), b);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBoolean_field::set_field_data(const char* data)
 | 
						|
{
 | 
						|
  if (data == NULL) data = "";
 | 
						|
  _on = toupper(*data) == 'X';
 | 
						|
}
 | 
						|
 | 
						|
const char* TBoolean_field::get_field_data() const
 | 
						|
{
 | 
						|
  return _on ? "X" : " ";
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TBoolean_field::parse_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  if (scanner.key() == "ME")
 | 
						|
  {
 | 
						|
    const bool tf = scanner.integer() ? TRUE : FALSE;   // Message TRUE or FALSE
 | 
						|
 | 
						|
    if (_message.items() == 0)
 | 
						|
    {
 | 
						|
      _message.add(new TToken_string(16));
 | 
						|
      _message.add(new TToken_string(16));
 | 
						|
    }
 | 
						|
    TToken_string& ts = (TToken_string&)_message[tf];
 | 
						|
    ts.add(scanner.line().strip_spaces());
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TMask_field::parse_item(scanner);
 | 
						|
}
 | 
						|
 | 
						|
void TBoolean_field::enable(bool on)
 | 
						|
{
 | 
						|
  _flags.enabled = on;
 | 
						|
  xvt_enable_control(_win, on);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TBoolean_field::on_hit()
 | 
						|
{                          
 | 
						|
  if (_handler)
 | 
						|
  {
 | 
						|
    bool ok = _handler(*this, K_SPACE);
 | 
						|
    if (!ok) return FALSE;
 | 
						|
  }
 | 
						|
  const int n = mask().is_running() ? xvt_get_checked_state(win()) : _on;
 | 
						|
  do_message(n);
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
bool TBoolean_field::on_key(KEY key)
 | 
						|
{
 | 
						|
  if (key == K_SPACE) 
 | 
						|
  {  
 | 
						|
    on_hit();
 | 
						|
    set_dirty();
 | 
						|
    return TRUE;
 | 
						|
  }  
 | 
						|
  return TMask_field::on_key(key);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Button_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TButton_field::TButton_field(TMask* m)
 | 
						|
: TMask_field(m)
 | 
						|
{
 | 
						|
  _flags.persistent = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
word TButton_field::class_id() const
 | 
						|
{ return CLASS_BUTTON_FIELD; }
 | 
						|
 | 
						|
void TButton_field::parse_head(TScanner& scanner)
 | 
						|
{
 | 
						|
  _width = scanner.integer();
 | 
						|
  if (_width < 1) _width = 9;
 | 
						|
  _size  = scanner.integer(); // Height
 | 
						|
  if (_size < 1) _size = 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TButton_field::parse_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  if (scanner.key() == "PI")
 | 
						|
  {            
 | 
						|
    const int bmp = scanner.integer();
 | 
						|
    _prompt << '#' << bmp;
 | 
						|
    return bmp > 0;
 | 
						|
  }
 | 
						|
  return TMask_field::parse_item(scanner);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TButton_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  long flags = CTL_FLAG_CENTER_JUST;
 | 
						|
 | 
						|
  switch (dlg())
 | 
						|
  {
 | 
						|
  case DLG_OK:
 | 
						|
    if (_prompt.empty())
 | 
						|
      _prompt = "Conferma";   
 | 
						|
    _virtual_key = _exit_key = K_ENTER;
 | 
						|
    flags |= CTL_FLAG_DEFAULT;
 | 
						|
    break;
 | 
						|
  case DLG_CANCEL:
 | 
						|
    if (_prompt.empty())
 | 
						|
      _prompt = "Annulla";
 | 
						|
    _virtual_key = _exit_key = K_ESC;
 | 
						|
    break;
 | 
						|
  case DLG_DELREC:  
 | 
						|
    if (_prompt.empty())
 | 
						|
      _prompt = "Elimina"; 
 | 
						|
    _virtual_key = 'E';
 | 
						|
    _exit_key = K_DEL;
 | 
						|
    break;
 | 
						|
  case DLG_PRINT:
 | 
						|
    if (_prompt.empty())
 | 
						|
      _prompt = "Stampa"; 
 | 
						|
    _virtual_key = 'S';
 | 
						|
    _exit_key = K_ENTER;
 | 
						|
    break;
 | 
						|
  case DLG_QUIT:
 | 
						|
    if (_prompt.empty())
 | 
						|
      _prompt = "Fine"; 
 | 
						|
    _virtual_key = K_F4;
 | 
						|
    _exit_key = K_QUIT;
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
  { 
 | 
						|
    _exit_key = 0;
 | 
						|
    TToken_string* message = (TToken_string*)_message.objptr(0);
 | 
						|
    if (message != NULL)
 | 
						|
    {
 | 
						|
      TToken_string msg(message->get(0), ','); 
 | 
						|
      const TFixed_string m(msg.get(0));
 | 
						|
      if (m == "EXIT") 
 | 
						|
        _exit_key = msg.get_int();
 | 
						|
      else 
 | 
						|
        if (msg.get_int() == 0) _exit_key = atoi(m);
 | 
						|
    }
 | 
						|
    const int n = _prompt.find('~');
 | 
						|
    _virtual_key = (n >= 0) ? toupper(_prompt[n+1]) : _exit_key;
 | 
						|
  }  
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
#if XWTWS == WMWS
 | 
						|
  const int diesis = _prompt.find('#');
 | 
						|
  if (diesis > 0) _prompt.cut(diesis);
 | 
						|
  _prompt.center_just(_width);
 | 
						|
#endif          
 | 
						|
  
 | 
						|
  wincreate(WC_PUSHBUTTON, _width + 2, _size, _prompt, parent, flags);
 | 
						|
}
 | 
						|
 | 
						|
void TButton_field::set_back_color(COLOR c) const
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
void TButton_field::enable(bool on)
 | 
						|
{
 | 
						|
  _flags.enabled = on;
 | 
						|
  xvt_enable_control(_win, on);
 | 
						|
}
 | 
						|
 | 
						|
void TButton_field::show(bool on)
 | 
						|
{
 | 
						|
  TMask_field::show(on);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TButton_field::on_key(KEY key)
 | 
						|
 | 
						|
{
 | 
						|
  if (key == K_SPACE)   
 | 
						|
  {
 | 
						|
    on_hit();
 | 
						|
    return TRUE;
 | 
						|
  }  
 | 
						|
  return TMask_field::on_key(key);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Date_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
word TDate_field::class_id() const
 | 
						|
{ return CLASS_DATE_FIELD; }
 | 
						|
 | 
						|
void TDate_field::create(WINDOW w)
 | 
						|
{
 | 
						|
  TEdit_field::create(w);
 | 
						|
  if (automagic())
 | 
						|
  {
 | 
						|
    TDate d(TODAY);
 | 
						|
    set(d.string());
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TDate_field::parse_head(TScanner&) {}
 | 
						|
 | 
						|
TDate_field::TDate_field(TMask* m) : TEdit_field(m)
 | 
						|
{
 | 
						|
  _size = _width = 10;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char* TDate_field::get_window_data() const
 | 
						|
{                                           
 | 
						|
  bool dummy;
 | 
						|
  TString16 str = TEdit_field::get_window_data();
 | 
						|
  return format_data(str, &dummy);
 | 
						|
}
 | 
						|
 | 
						|
void TDate_field::set_window_data(const char* data)
 | 
						|
{                                           
 | 
						|
  const TDate d(data);
 | 
						|
  TEdit_field::set_window_data(d.string());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// @mfunc Permette di formattare la data secondo i flag correnti
 | 
						|
//
 | 
						|
// @rdesc Ritorna la data formattata
 | 
						|
const char* TDate_field::format_data(
 | 
						|
  const char* datum, // @parm Stringa contenenete la data da formattare
 | 
						|
  bool* ch) const    // @parm Indica se e' stata cambiato il formato rispetto alla stringa passsata
 | 
						|
  
 | 
						|
  // @comm Permette di gestire anche alcuni date particolari come:
 | 
						|
  //
 | 
						|
  // @flag IERI | Inserisce la data del giorno precedente a quella del sistema
 | 
						|
  // @flag OGGI | Inserisce la data del sistema
 | 
						|
  // @flag DOMANI | Inserisce la data del giorno successivo a quella del sistema
 | 
						|
  // @flag PRIMO | Primo giorno dell'anno (01-01-aa)
 | 
						|
  // @flag ULTIMO | Ultimo giorno dell'anno (31-12-aa)
 | 
						|
  // @flag NATALE | Giorno di natale (25-12-aa)
 | 
						|
{
 | 
						|
  bool changed = FALSE;
 | 
						|
  fpark = datum;
 | 
						|
  fpark.trim();
 | 
						|
  if (fpark.not_empty())
 | 
						|
  {
 | 
						|
    if (isdigit(fpark[0]))
 | 
						|
    {
 | 
						|
      if (fpark.len() == 6)      // Fix century (for this millenium only)
 | 
						|
      {
 | 
						|
        fpark.insert("19", 4);
 | 
						|
        changed = TRUE;
 | 
						|
      }
 | 
						|
      for (int meno = 2; meno <= 5; meno += 3)
 | 
						|
        if (fpark[meno] != '-')
 | 
						|
        {
 | 
						|
          fpark.insert("-", meno);
 | 
						|
          changed = TRUE;
 | 
						|
        }
 | 
						|
      if (fpark.len() == 8)      // Fix century (for this millenium only)
 | 
						|
      {
 | 
						|
        fpark.insert("19", 6);
 | 
						|
        changed = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      TDate g(TODAY);
 | 
						|
      fpark.upper();
 | 
						|
      if (fpark == "IERI")
 | 
						|
      {
 | 
						|
        --g;
 | 
						|
        changed = TRUE;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        if (fpark == "DOMANI")
 | 
						|
        {
 | 
						|
          ++g;
 | 
						|
          changed = TRUE;
 | 
						|
        }
 | 
						|
      TString16 gstring(g.string());
 | 
						|
      if (fpark == "PRIMO") 
 | 
						|
      {
 | 
						|
        gstring.overwrite("01-01", 0);
 | 
						|
        changed = TRUE;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        if (fpark == "NATALE")
 | 
						|
        {
 | 
						|
          gstring.overwrite("25-12", 0);
 | 
						|
          changed = TRUE;
 | 
						|
        }
 | 
						|
        else
 | 
						|
          if (fpark == "ULTIMO")
 | 
						|
          {
 | 
						|
            gstring.overwrite("31-12", 0);
 | 
						|
            changed = TRUE;
 | 
						|
          }
 | 
						|
          else
 | 
						|
            if (fpark == "OGGI")
 | 
						|
              changed = TRUE;
 | 
						|
      if (changed) fpark = gstring;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (ch) 
 | 
						|
    *ch = changed;
 | 
						|
 | 
						|
  return fpark;
 | 
						|
}
 | 
						|
 | 
						|
bool TDate_field::on_key(KEY key)
 | 
						|
{
 | 
						|
  if (to_check(key))
 | 
						|
  {
 | 
						|
    bool changed = FALSE;                  
 | 
						|
    
 | 
						|
    TFixed_string data(format_data(get_window_data(),&changed), 15);  
 | 
						|
 | 
						|
    if (data.not_empty())
 | 
						|
    {
 | 
						|
      //      TDate d(data);
 | 
						|
      if (!TDate::isdate(data))
 | 
						|
      {
 | 
						|
        error_box("Data errata o formato non valido");
 | 
						|
        return FALSE;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        if (changed)
 | 
						|
          TMask_field::set_window_data(data);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TEdit_field::on_key(key);
 | 
						|
}
 | 
						|
 | 
						|
bool TDate_field::autosave(TRelation* r) const
 | 
						|
{         
 | 
						|
  const char* td = get();
 | 
						|
  if (right_justified())
 | 
						|
  {
 | 
						|
    TDate d(td);
 | 
						|
    td = d.string(ANSI);
 | 
						|
  }
 | 
						|
  if (field())
 | 
						|
  {
 | 
						|
    field()->write(td, r);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
const char* TDate_field::picture_data(const char* data, bool video) const
 | 
						|
{
 | 
						|
  return video ? format_data(data) : data; 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Real_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TReal_field::TReal_field(TMask* m) : TEdit_field(m)
 | 
						|
{}
 | 
						|
 | 
						|
word TReal_field::class_id() const
 | 
						|
{ return CLASS_REAL_FIELD; }
 | 
						|
 | 
						|
void TReal_field::create(WINDOW w)
 | 
						|
{
 | 
						|
  TEdit_field::create(w);
 | 
						|
  _flags.rightjust = TRUE;
 | 
						|
  
 | 
						|
  if (_flags.firm)
 | 
						|
    set(::format("%ld", main_app().get_firm())); 
 | 
						|
  else
 | 
						|
    if (automagic())
 | 
						|
    {
 | 
						|
      TDate d(TODAY);
 | 
						|
      set(::format("%d", d.year()));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
bool TReal_field::autoload(const TRelation* r)
 | 
						|
{
 | 
						|
  const bool ok = TMask_field::autoload(r);
 | 
						|
  if (ok && _flags.zerofilled && _str.not_empty())
 | 
						|
  {  
 | 
						|
    int s = size();
 | 
						|
    if (roman())
 | 
						|
    {
 | 
						|
      s = decimals();
 | 
						|
      if (s < 1) s = 4;
 | 
						|
    }
 | 
						|
    _str.right_just(s, '0');
 | 
						|
  }  
 | 
						|
  
 | 
						|
  return ok;  
 | 
						|
}
 | 
						|
 | 
						|
bool TReal_field::on_key(KEY key)
 | 
						|
{
 | 
						|
  if (to_check(key))
 | 
						|
  {
 | 
						|
    if (roman())
 | 
						|
    {
 | 
						|
      const int r = atoi(get_window_data());
 | 
						|
      if (r < 0) return error_box("Numero romano errato");
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      const char* n = get();
 | 
						|
      if (*n && !real::is_real(n))
 | 
						|
        return error_box("Valore numerico non valido");
 | 
						|
      if (_flags.uppercase && *n == '-')
 | 
						|
        return error_box("Il numero deve essere positivo");
 | 
						|
      if (_flags.firm)
 | 
						|
      {                         
 | 
						|
        const long f = atol(n);
 | 
						|
        if (f > 0 && prefix().exist(f))
 | 
						|
          main_app().set_firm(f);
 | 
						|
      }  
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TEdit_field::on_key(key);
 | 
						|
}
 | 
						|
 | 
						|
void TReal_field::parse_head(TScanner& scanner)
 | 
						|
{
 | 
						|
  _size  = scanner.integer();
 | 
						|
 | 
						|
#ifdef DBG      
 | 
						|
  if (_size < 1)
 | 
						|
  {
 | 
						|
    _size = 9;
 | 
						|
    yesnofatal_box("Il campo %d ha dimensione nulla (uso %d)", dlg(), _size);
 | 
						|
  }
 | 
						|
#endif
 | 
						|
  
 | 
						|
  _width = _size;
 | 
						|
  _decimals = scanner.integer();
 | 
						|
}
 | 
						|
 | 
						|
void TReal_field::set_window_data(const char* data)
 | 
						|
{       
 | 
						|
  if (data == NULL) data = "";
 | 
						|
 | 
						|
  if (roman())
 | 
						|
  {
 | 
						|
    data = itor(atoi(data));
 | 
						|
  }
 | 
						|
  else
 | 
						|
  { 
 | 
						|
    real n(data);
 | 
						|
    if (!n.is_zero())
 | 
						|
    {
 | 
						|
      if (exchangeable() && decimals())
 | 
						|
      {
 | 
						|
        const real& e = mask().exchange();
 | 
						|
        n /= e;
 | 
						|
      }
 | 
						|
      if (_picture.empty())
 | 
						|
      {
 | 
						|
        const char pad = _flags.zerofilled ? '0' : ' ';
 | 
						|
        data = n.stringa(_size, _decimals, pad);
 | 
						|
      }  
 | 
						|
      else
 | 
						|
      {
 | 
						|
        fpark = n.string(_picture);
 | 
						|
        fpark.right_just(_size);
 | 
						|
        data = fpark;
 | 
						|
      }  
 | 
						|
    } 
 | 
						|
    else data = "";
 | 
						|
  }
 | 
						|
  TMask_field::set_window_data(data);
 | 
						|
}
 | 
						|
 | 
						|
const char* TReal_field::get_window_data() const
 | 
						|
{
 | 
						|
  TEdit_field::get_window_data();
 | 
						|
  if (roman())
 | 
						|
  {
 | 
						|
    int r = atoi(fpark);
 | 
						|
    if (r == 0) r = rtoi(fpark);
 | 
						|
    if (r > 0)
 | 
						|
    {
 | 
						|
      int s = decimals();
 | 
						|
      if (s < 1) s = 4;
 | 
						|
      if (_flags.zerofilled)
 | 
						|
        fpark.format("%0*d", s, r);
 | 
						|
      else
 | 
						|
        fpark.format("%*d", s, r);
 | 
						|
    }
 | 
						|
    else fpark.cut(0);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    fpark = real::ita2eng(fpark);
 | 
						|
    if (exchangeable() && decimals())
 | 
						|
    {      
 | 
						|
      real n(fpark);
 | 
						|
      const real& e = mask().exchange();
 | 
						|
      n *= e;
 | 
						|
      if (n.is_zero()) fpark.cut(0);
 | 
						|
      else fpark = n.string();
 | 
						|
    }
 | 
						|
  }     
 | 
						|
 | 
						|
  return fpark;
 | 
						|
} 
 | 
						|
 | 
						|
const char* TReal_field::picture_data(const char* data, bool video) const
 | 
						|
{
 | 
						|
  if (video)
 | 
						|
  {
 | 
						|
    fpark = real::ita2eng(data);
 | 
						|
    if (_flags.zerofilled && fpark.not_empty())
 | 
						|
      fpark.right_just(_size, '0');
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {        
 | 
						|
    const real n(data);
 | 
						|
    if (!n.is_zero())
 | 
						|
    {
 | 
						|
      if (_picture.empty())
 | 
						|
      {            
 | 
						|
        const char pad = _flags.zerofilled ? '0' : ' ';
 | 
						|
        fpark = n.stringa(_size, _decimals, pad);
 | 
						|
      }  
 | 
						|
      else
 | 
						|
        fpark = n.string(_picture);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      fpark.cut(0);    
 | 
						|
  }
 | 
						|
  
 | 
						|
  return fpark.trim();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TReal_field::set_decimals(int d) 
 | 
						|
{ 
 | 
						|
  _decimals = d; 
 | 
						|
  if (_picture[0] == '.')
 | 
						|
  {
 | 
						|
    if (d > 0) _picture.format(".%d", d);
 | 
						|
    else _picture = ".";
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TReal_field::exchange(bool show_value, const real& nuo)
 | 
						|
{                                
 | 
						|
  const int dec = show_value ? 2 : 0;            // Quanti decimali voglio
 | 
						|
  const bool value = decimals() != 0;            // Sono attualmente in valuta ?
 | 
						|
  
 | 
						|
  if (show_value == value && show_value) return; // Se cambio da valuta a valuta esco subito! 
 | 
						|
  
 | 
						|
  if (mask().is_running())
 | 
						|
  {
 | 
						|
    const char* n = get_window_data();
 | 
						|
    if (*n)
 | 
						|
    {
 | 
						|
      const real& vec = mask().exchange();
 | 
						|
      real r(n); 
 | 
						|
      if (!show_value) 
 | 
						|
        r *= nuo;
 | 
						|
      r /= vec;
 | 
						|
      r.round(dec);
 | 
						|
      set_decimals(dec);
 | 
						|
      TEdit_field::set_window_data(r.string(_picture));
 | 
						|
    }  
 | 
						|
  }  
 | 
						|
  
 | 
						|
  if (decimals() != dec)
 | 
						|
    set_decimals(dec);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// List_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TList_field::TList_field(TMask* m) : TMask_field(m)
 | 
						|
{}
 | 
						|
 | 
						|
word TList_field::class_id() const
 | 
						|
{
 | 
						|
  return CLASS_LIST_FIELD;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::read_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  TToken_string ts(scanner.string());
 | 
						|
  _codes.add(ts.get());
 | 
						|
  _values.add(ts.get());
 | 
						|
 | 
						|
  ts = "";
 | 
						|
  while (scanner.popkey() == "ME")
 | 
						|
    ts.add(scanner.line().strip_spaces());
 | 
						|
  scanner.push();
 | 
						|
 | 
						|
  _message.add(ts);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::parse_head(TScanner& scanner)
 | 
						|
{
 | 
						|
  _size = scanner.integer();
 | 
						|
  _width = scanner.integer();
 | 
						|
  if (_width < 1) _width = _size+3;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TList_field::parse_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  if (scanner.key() == "IT")            // ITEM
 | 
						|
  {
 | 
						|
    read_item(scanner);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (scanner.key() == "LI")            // LISTITEM
 | 
						|
  {
 | 
						|
    TScanner sc(scanner.pop());
 | 
						|
    while (sc.popkey() == "IT")         // ITEM
 | 
						|
      read_item(sc);
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TMask_field::parse_item(scanner);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TList_field::items() const
 | 
						|
{
 | 
						|
  return _codes.items();
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Aggiunge delle voci al list sheet
 | 
						|
void TList_field::add_item(   
 | 
						|
  const char* s) // @parm Voci da aggiungere
 | 
						|
  
 | 
						|
  // @comm Se il parametro <p s> e' passato con il formato di una <c TToken_string> vengono
 | 
						|
  //                     aggiunte tante voci quanti sono gli elementi.
 | 
						|
{
 | 
						|
  TToken_string t(s);         
 | 
						|
  const TString16 item(t.get());
 | 
						|
  const int pos = _codes.get_pos(item);
 | 
						|
  
 | 
						|
  if (pos < 0 )
 | 
						|
  {                                         
 | 
						|
    _codes.add(item);
 | 
						|
    xvt_list_add(win(), -1, (char*)t.get());
 | 
						|
  }     
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::delete_item(const char* s)
 | 
						|
{
 | 
						|
  TString16 t(s);         
 | 
						|
  const int pos = _codes.get_pos(t);
 | 
						|
  
 | 
						|
  if (pos >= 0 )
 | 
						|
  {                                         
 | 
						|
    _codes.destroy(pos);
 | 
						|
    xvt_list_rem(win(), pos);
 | 
						|
    if (mask().is_running())
 | 
						|
    {
 | 
						|
      xvt_list_set_sel(win(), 0, TRUE);
 | 
						|
      if (shown())     on_hit();
 | 
						|
    }
 | 
						|
  }     
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::add_list()
 | 
						|
{
 | 
						|
  if (roman() && _codes.items() < 12)
 | 
						|
  {
 | 
						|
    TString csafe, vsafe;
 | 
						|
    if (atoi(_codes) > 0)
 | 
						|
    {
 | 
						|
      csafe = _codes; _codes = "";
 | 
						|
      vsafe = _values; _values = "";
 | 
						|
    }
 | 
						|
    _codes.add("01|02|03|04|05|06|07|08|09|10|11|12");
 | 
						|
    _values.add("Gennaio|Febbraio|Marzo|Aprile|Maggio|Giugno");
 | 
						|
    _values.add("Luglio|Agosto|Settembre|Ottobre|Novembre|Dicembre");
 | 
						|
    if (atoi(csafe) > 0)
 | 
						|
    {
 | 
						|
      _codes.add(csafe);
 | 
						|
      _values.add(vsafe);
 | 
						|
      if (_message.objptr(0))
 | 
						|
      {
 | 
						|
        _message.add(_message[0], _codes.items()-1);
 | 
						|
        _message.add(NULL, 0);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  SLIST lst = xvt_slist_create();
 | 
						|
  for (const char* item = _values.get(0); item; item = _values.get())
 | 
						|
    xvt_slist_add_at_elt(lst, (SLIST_ELT)NULL, (char*)item, 0L);
 | 
						|
  xvt_list_add(win(), -1, (char*)lst);
 | 
						|
  xvt_slist_destroy(lst);
 | 
						|
 | 
						|
  const char* init = "";
 | 
						|
  if (roman() && automagic())
 | 
						|
    init = format("%02d", TDate(TODAY).month());
 | 
						|
  set_field_data(init);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @mfunc Sostituisce alle voci correnti quelle passate come parametri
 | 
						|
void TList_field::replace_items(
 | 
						|
  const char* codes,  // @parm Codici da sostituire ai correnti
 | 
						|
  const char* values) // @parm Voci da sostituire a quelle correnti
 | 
						|
 | 
						|
  // @comm I parametri <p codes> e <p values> devono essere TToken_string se lo voci da sostiutire
 | 
						|
  //                     sono piu' di una
 | 
						|
{
 | 
						|
  _codes = codes;
 | 
						|
  _values = values;
 | 
						|
 | 
						|
  if (win() != NULL_WIN)
 | 
						|
  {
 | 
						|
    xvt_list_clear(win());
 | 
						|
    add_list();
 | 
						|
    current(0);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  const int len = create_prompt(parent);
 | 
						|
  _x += len;
 | 
						|
 | 
						|
  wincreate(WC_LISTBUTTON, _width, 5, "", parent,0);
 | 
						|
  add_list();
 | 
						|
}
 | 
						|
 | 
						|
void TList_field::set_back_color(COLOR c) const
 | 
						|
{
 | 
						|
  if (_promptwin != NULL_WIN)
 | 
						|
    xvt_set_ctrl_back_color(_promptwin, c);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TList_field::str2curr(const char* data)
 | 
						|
{
 | 
						|
  TString16 str(data);
 | 
						|
 | 
						|
  if (roman() && str.len() < 2)
 | 
						|
    str.insert("0",0);
 | 
						|
  if (_flags.uppercase)
 | 
						|
    str.upper();        
 | 
						|
 | 
						|
  int i = str.not_empty() ? _codes.get_pos(str) : 0;
 | 
						|
 | 
						|
  if (i < 0)      // Se non trova il codice ritenta dopo trim
 | 
						|
  {
 | 
						|
    for (i = 0; str[i] == '0' || str[i] == ' '; i++);
 | 
						|
    if (i > 0)
 | 
						|
    {
 | 
						|
      str.ltrim(i);
 | 
						|
      i = _codes.get_pos(str);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (i < 0)
 | 
						|
  {
 | 
						|
    if (items() && str.not_empty())
 | 
						|
      yesnofatal_box("'%s' non e' un valore valido per il campo %s: %d",
 | 
						|
                     data, prompt(), dlg());
 | 
						|
    i = 0;
 | 
						|
  }
 | 
						|
  return i;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::set_window_data(const char* data)
 | 
						|
{
 | 
						|
  CHECKD(win(), "Control window not initialized ", dlg());
 | 
						|
  const int i = str2curr(data);
 | 
						|
  current(i);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TList_field::current(int n)
 | 
						|
{
 | 
						|
  xvt_list_set_sel(win(), n, TRUE);
 | 
						|
}
 | 
						|
 | 
						|
int TList_field::current() const
 | 
						|
{
 | 
						|
  const int sel = xvt_list_get_sel_index(win());
 | 
						|
#ifdef DBG
 | 
						|
  if (sel < 0 && items() > 0)
 | 
						|
    error_box("Lista senza selezione nel campo %d", dlg());
 | 
						|
#endif
 | 
						|
  return sel;
 | 
						|
}
 | 
						|
 | 
						|
const char* TList_field::get_window_data() const
 | 
						|
{                                    
 | 
						|
  const int c = current();
 | 
						|
  const char* v = ((TList_field*)this)->_codes.get(c);
 | 
						|
  return v;
 | 
						|
}
 | 
						|
 | 
						|
void TList_field::set_field_data(const char* data)
 | 
						|
{         
 | 
						|
  const int i = str2curr(data);
 | 
						|
  _str = _codes.get(i);    
 | 
						|
}
 | 
						|
 | 
						|
bool TList_field::on_hit()
 | 
						|
{
 | 
						|
  if (_handler)
 | 
						|
  {
 | 
						|
    bool ok = _handler(*this, K_SPACE);
 | 
						|
    if (!ok) return FALSE;
 | 
						|
  }
 | 
						|
  const int n = mask().is_running() ? current() : str2curr(_str);
 | 
						|
  do_message(n);
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
const char* TList_field::get_field_data() const
 | 
						|
{
 | 
						|
  return _str;
 | 
						|
}
 | 
						|
 | 
						|
bool TList_field::on_key(KEY key)
 | 
						|
{
 | 
						|
  if (key >= '0' && key <= 'z')
 | 
						|
  {
 | 
						|
    const int index = current();
 | 
						|
    CHECK(index >= 0, "List with no selection!");
 | 
						|
    int newindex = -1;
 | 
						|
 | 
						|
#if XVTWS == WMWS
 | 
						|
    if (key >= 'A' && key <= 'z')
 | 
						|
    {
 | 
						|
      for (int i = index+1; i != index; i++)
 | 
						|
      {
 | 
						|
        char item[16];
 | 
						|
        bool flag;
 | 
						|
 | 
						|
        do
 | 
						|
        {
 | 
						|
          flag = xvt_list_get_elt(win(), i, item, 16);
 | 
						|
          if (!flag)
 | 
						|
          {
 | 
						|
            CHECK(i, "La lista e' vuota!");
 | 
						|
            i = -1;
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        } while (!flag);
 | 
						|
        if (flag && toupper(*item) == toupper(key))
 | 
						|
        {
 | 
						|
          newindex = i;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      } // for
 | 
						|
    } // alphabetic
 | 
						|
#endif
 | 
						|
 | 
						|
    if (key >= '0' && key <= '9')
 | 
						|
    {
 | 
						|
      newindex = (key == '0') ? 10 : key - '1';
 | 
						|
      if (newindex > items())
 | 
						|
      {
 | 
						|
        newindex = -1;
 | 
						|
        beep();
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (newindex >= 0)
 | 
						|
      current(newindex);
 | 
						|
    /*    
 | 
						|
       {                        
 | 
						|
       xvt_list_suspend(win());
 | 
						|
       xvt_list_set_sel(win(), index, FALSE);
 | 
						|
       xvt_list_set_sel(win(), newindex, TRUE);
 | 
						|
       xvt_list_resume(win());
 | 
						|
       }
 | 
						|
       */    
 | 
						|
  }
 | 
						|
 | 
						|
#if XVTWS == VMWS
 | 
						|
  if (key == K_TAB && class_id() == CLASS_LIST_FIELD)
 | 
						|
    dispacth_e_char(win(), K_F9);
 | 
						|
#endif
 | 
						|
  
 | 
						|
  if (_validate_func >= 0 && (key == K_TAB || key == K_ENTER))
 | 
						|
  {
 | 
						|
    const bool ok = ::validate(_validate_func, *this, key, _validate_parms);
 | 
						|
    if (!ok) 
 | 
						|
    {
 | 
						|
      if (_warning.not_empty()) 
 | 
						|
        return error_box(_warning);
 | 
						|
    }    
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (key == K_SPACE) on_hit();
 | 
						|
 | 
						|
  return TMask_field::on_key(key);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRadio_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TRadio_field::TRadio_field(TMask* mask)
 | 
						|
: TList_field(mask), _nitems(0), _active_item(0)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
word TRadio_field::class_id() const
 | 
						|
{
 | 
						|
  return CLASS_RADIO_FIELD;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  const short id = dlg();     // Salva il control id
 | 
						|
  const int items = _codes.items();
 | 
						|
 | 
						|
  if (_prompt.not_empty())
 | 
						|
  {
 | 
						|
    const int dy = _flags.zerofilled ? 3 : items+2;
 | 
						|
    create_prompt(parent, _width, dy);
 | 
						|
  }
 | 
						|
  _x++; _y++;
 | 
						|
  _values.restart();
 | 
						|
 | 
						|
  const char* s;
 | 
						|
  
 | 
						|
  const int width = _flags.zerofilled ? (_width-2)/items-1 : _width-2;
 | 
						|
  for(_nitems = 0; (s = _values.get()) != NULL; _nitems++)
 | 
						|
  {
 | 
						|
    CHECKD(_nitems < MAX_RADIO, "Too many items in radio button ", id);
 | 
						|
 | 
						|
    wincreate(WC_RADIOBUTTON, width, 1, s, parent,0);
 | 
						|
    _radio_ctl_win[_nitems] = _win;
 | 
						|
    _dlg += 1000;
 | 
						|
    
 | 
						|
    if (_flags.zerofilled)
 | 
						|
      _x += width+1;
 | 
						|
    else
 | 
						|
      _y++;
 | 
						|
  }
 | 
						|
  _radio_ctl_win[_nitems] = NULL_WIN;   // Comodo per debug
 | 
						|
 | 
						|
  _dlg = id;  // Ripristina control id
 | 
						|
 | 
						|
  set_field_data("");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::set_back_color(COLOR c) const
 | 
						|
{                          
 | 
						|
  TList_field::set_back_color(c);
 | 
						|
  xvt_set_ctrl_back_color(win(), c);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::destroy()
 | 
						|
{
 | 
						|
  if (_promptwin)
 | 
						|
  {     xvt_vobj_destroy(_promptwin); _promptwin = NULL_WIN; }
 | 
						|
 | 
						|
  for(int i = 0; i < _nitems; i++)
 | 
						|
  {
 | 
						|
    xvt_vobj_destroy(_radio_ctl_win[i]);
 | 
						|
    _radio_ctl_win[i] = NULL_WIN;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int TRadio_field::current() const
 | 
						|
{
 | 
						|
  const int c = xvt_get_checked_radio(_radio_ctl_win, _nitems);
 | 
						|
  return c;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::current(int n)
 | 
						|
{
 | 
						|
  _active_item = n;
 | 
						|
  xvt_check_radio_button(win(), _radio_ctl_win, _nitems);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::check_radiobutton(WINDOW checked)
 | 
						|
{
 | 
						|
  for(int i = 0; i < _nitems && checked != _radio_ctl_win[i]; i++);
 | 
						|
  CHECK(i < _nitems, "Trying to check an invalid radio button");
 | 
						|
  current(i);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::enable(bool on)
 | 
						|
{
 | 
						|
  _flags.enabled = on;
 | 
						|
  for(int i = 0; i < _nitems; i++)
 | 
						|
    xvt_enable_control(_radio_ctl_win[i], on);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TRadio_field::show(bool on)
 | 
						|
{
 | 
						|
  if (_promptwin)
 | 
						|
    xvt_vobj_set_visible(_promptwin, on);
 | 
						|
 | 
						|
  for(int i = 0; i < _nitems; i++)
 | 
						|
    xvt_vobj_set_visible(_radio_ctl_win[i], on);
 | 
						|
  _flags.shown = on;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Sposta il focus dal radio button
 | 
						|
//
 | 
						|
// @rdesc Ritorna TRUE se il focus ha lasciato il radio button
 | 
						|
bool TRadio_field::move_focus(
 | 
						|
  int d) // @parm Numero di posizioni di spostamento del focus
 | 
						|
 | 
						|
  // @comm Poiche' la gestione dei radio button e' gestita direttamente da Windows
 | 
						|
  //       in caso si prema TAB o SHIF+TAB all'interno si passa da una voce
 | 
						|
  //       all'altra e non al campo successivo o precedente.
 | 
						|
{
 | 
						|
  const int act = _active_item + d;
 | 
						|
  if (act >= _nitems || act < 0)
 | 
						|
  {
 | 
						|
    _active_item = current();
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  xvt_set_front_control(_radio_ctl_win[_active_item = act]);
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TGroup_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TGroup_field::TGroup_field(TMask* mask) : TMask_field(mask)
 | 
						|
{
 | 
						|
  _flags.persistent = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
// _size means _heigth
 | 
						|
void TGroup_field::parse_head(TScanner& scanner)
 | 
						|
{
 | 
						|
  _width = scanner.integer();
 | 
						|
  _size  = scanner.integer();
 | 
						|
}
 | 
						|
 | 
						|
void TGroup_field::create(WINDOW parent)
 | 
						|
{
 | 
						|
  const long f = _flags.rightjust ? CTL_FLAG_MULTIPLE : 0;
 | 
						|
  wincreate(WC_GROUPBOX, _width, _size, _prompt, parent, f);
 | 
						|
}
 | 
						|
 | 
						|
void TGroup_field::set_back_color(COLOR c) const
 | 
						|
{
 | 
						|
  xvt_set_ctrl_back_color(win(), c);
 | 
						|
}
 | 
						|
 | 
						|
void TGroup_field::set_window_data(const char* data)
 | 
						|
{ xvt_set_title(win(), data); }
 | 
						|
 | 
						|
void TGroup_field::set_field_data(const char* data)
 | 
						|
{ xvt_set_title(win(), data); }
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMemo_field
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TMemo_field::TMemo_field(TMask* mask) : TMask_field(mask), _te(BAD_TXEDIT)
 | 
						|
{}
 | 
						|
 | 
						|
TMemo_field::~TMemo_field()
 | 
						|
{                     
 | 
						|
  _te = BAD_TXEDIT;
 | 
						|
}
 | 
						|
 | 
						|
void TMemo_field::parse_head(TScanner& scanner)
 | 
						|
{
 | 
						|
  _width = scanner.integer();
 | 
						|
  _size  = scanner.integer();
 | 
						|
}
 | 
						|
 | 
						|
void TMemo_field::create(WINDOW parent)
 | 
						|
{                     
 | 
						|
  const short dx = _width;
 | 
						|
  const short dy = _size-1;
 | 
						|
 | 
						|
  TMask_field::create(parent);
 | 
						|
 | 
						|
  WIN_DEF wd;
 | 
						|
  wd.wtype        = WO_TE;
 | 
						|
  wd.rct          = resize_rect(_x, _y+1, dx, dy, WC_EDIT, parent);
 | 
						|
  wd.text         = NULL;
 | 
						|
  wd.units        = U_PIXELS;
 | 
						|
  wd.v.tx.attrib  = TX_NOMENU | TX_BORDER | TX_AUTOVSCROLL | TX_WRAP;
 | 
						|
  wd.v.tx.font_id = xvt_dwin_get_font(win());
 | 
						|
  wd.v.tx.margin  = wd.rct.right - wd.rct.left;
 | 
						|
  wd.v.tx.limit   = 256;
 | 
						|
  wd.v.tx.tx_id   = dlg();
 | 
						|
  _te             = xvt_tx_create_def(&wd, parent, NULL);
 | 
						|
  CHECK(_te != BAD_TXEDIT, "Can't create a memo field");  
 | 
						|
  
 | 
						|
  enable_default();     // Setta colori default
 | 
						|
}
 | 
						|
 | 
						|
void TMemo_field::set_back_color(COLOR) const
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void TMemo_field::highlight() const
 | 
						|
{
 | 
						|
  xvt_tx_set_active(_te);
 | 
						|
}
 | 
						|
 | 
						|
bool TMemo_field::on_key(KEY k)
 | 
						|
{
 | 
						|
  return TMask_field::on_key(k);
 | 
						|
}
 | 
						|
 | 
						|
void TMemo_field::enable(bool on)
 | 
						|
{
 | 
						|
  TMask_field::enable(on);
 | 
						|
  
 | 
						|
  unsigned attr = xvt_tx_get_attr(_te);
 | 
						|
  if (on) 
 | 
						|
  {
 | 
						|
    xvt_tx_set_colors(_te, NORMAL_COLOR, COLOR_BLACK, NORMAL_BACK_COLOR);
 | 
						|
    attr &= ~TX_READONLY; 
 | 
						|
  }  
 | 
						|
  else  
 | 
						|
  {
 | 
						|
    xvt_tx_set_colors(_te, DISABLED_COLOR, COLOR_BLACK, DISABLED_BACK_COLOR);
 | 
						|
    attr |= TX_READONLY;
 | 
						|
  }  
 | 
						|
  xvt_tx_set_attr(_te, attr);  
 | 
						|
}
 | 
						|
 | 
						|
void TMemo_field::show(bool on)
 | 
						|
{
 | 
						|
  TMask_field::show(on);
 | 
						|
}
 | 
						|
 | 
						|
bool TMemo_field::autoload(const TRelation* r)
 | 
						|
{
 | 
						|
  const TFieldref* f = field();
 | 
						|
  xvt_tx_clear(_te);
 | 
						|
  if (f != NULL)
 | 
						|
  {       
 | 
						|
    TTextfile txt;
 | 
						|
    r->lfile(f->file()).get_memo(f->name(), txt);             
 | 
						|
    
 | 
						|
    xvt_tx_suspend(_te);
 | 
						|
    for (T_LNUM i = 0; i < (T_LNUM)txt.lines(); i++)
 | 
						|
      xvt_tx_add_par(_te, i, (char*)txt.line(i));
 | 
						|
    xvt_tx_resume(_te);  
 | 
						|
    return i > 0;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TMemo_field::autosave(TRelation* r) const
 | 
						|
{
 | 
						|
  const TFieldref* f = field();
 | 
						|
  if (dirty() && f != NULL)
 | 
						|
  {             
 | 
						|
    const T_PNUM num_par = xvt_tx_get_num_pars(_te);
 | 
						|
    TTextfile txt;
 | 
						|
    TString par(256);
 | 
						|
    TString256 line; 
 | 
						|
 | 
						|
    for (T_PNUM p = 0; p < num_par; p++)
 | 
						|
    {
 | 
						|
      par.cut(0);
 | 
						|
      const T_LNUM lines = xvt_tx_get_num_par_lines(_te, p);
 | 
						|
      for (T_LNUM l = 0; l < lines; l++)
 | 
						|
      {                                                         
 | 
						|
        unsigned len;
 | 
						|
        xvt_tx_get_line(_te, p, A_LOCK, l, &len);
 | 
						|
        const char* s = xvt_tx_get_line(_te, p, A_GET, l, &len);
 | 
						|
        CHECK(s, "Null memo line");
 | 
						|
        line.strncpy(s, len);
 | 
						|
        xvt_tx_get_line(_te, p, A_UNLOCK, l, &len);
 | 
						|
 | 
						|
        if (par.not_empty()) par << ' ';
 | 
						|
        par << line;
 | 
						|
      }
 | 
						|
      txt.append(par);
 | 
						|
    }
 | 
						|
    r->lfile(f->file()).put(f->name(), txt);             
 | 
						|
    return num_par > 0;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 |