git-svn-id: svn://10.65.10.50/branches/R_10_00@22884 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1941 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1941 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <dongle.h>
 | 
						|
#include <execp.h>
 | 
						|
#include <msksheet.h>
 | 
						|
#include <recarray.h>
 | 
						|
#include <recset.h>
 | 
						|
#include <relapp.h>
 | 
						|
#include <sheet.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
 | 
						|
#include "../mg/anamag.h"
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TBrowse_button
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TBrowse_button::TBrowse_button(TEdit_field* f) 
 | 
						|
              : _fld(f)
 | 
						|
{ }
 | 
						|
  
 | 
						|
TBrowse_button::~TBrowse_button()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TEditable_field& TBrowse_button::field(short id) const
 | 
						|
{
 | 
						|
  if (id > 0)
 | 
						|
  {
 | 
						|
    TMask_field& f = _fld->mask().field(id); 
 | 
						|
    CHECKD(f.is_editable(), "Can't use in a browse the field ", id);
 | 
						|
    return (TEditable_field&)f;
 | 
						|
  }
 | 
						|
  return *_fld;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TList_sheet
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TList_sheet::TList_sheet(TEdit_field* f, const char* caption, const char* head)
 | 
						|
           : TBrowse_button(f), _row(-1), _caption(caption), _head(head)
 | 
						|
{ }
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TList_sheet::~TList_sheet()
 | 
						|
{ }
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TList_sheet::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  _inp_id.add(scanner.pop());
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TList_sheet::parse_item(TScanner& scanner)
 | 
						|
{
 | 
						|
  _data.add(new TToken_string(scanner.string()));
 | 
						|
}
 | 
						|
 | 
						|
// 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_items()) 
 | 
						|
    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 = field().atodlg(fld);
 | 
						|
      if (id > 0)
 | 
						|
      { 
 | 
						|
        const TMask_field& f = field(id);
 | 
						|
        if (f.class_id() == CLASS_ZOOM_FIELD)
 | 
						|
        {
 | 
						|
          const TZoom_field& z = (TZoom_field&)f;
 | 
						|
          rowsel.add(z.get_first_line());
 | 
						|
        }
 | 
						|
        else
 | 
						|
           rowsel.add(f.get());
 | 
						|
      }
 | 
						|
      else rowsel.add("");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  TString fd, it;
 | 
						|
  for (int i = 0 ; i < _data.items(); i++)
 | 
						|
  {
 | 
						|
    TToken_string& ts =_data.row(i);
 | 
						|
 | 
						|
    ts.restart();
 | 
						|
    const char * item;
 | 
						|
    for (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 = _data.row(_row);
 | 
						|
  rowsel.restart();
 | 
						|
  for (const char* fld = _out_id.get(); fld; fld = _out_id.get())
 | 
						|
  {
 | 
						|
    const short id = field().atodlg(fld);
 | 
						|
    TMask_field& f = field(id);
 | 
						|
    const char* val = rowsel.get();
 | 
						|
		if (t != STARTING_CHECK || f.field() == NULL)
 | 
						|
		{           
 | 
						|
			const bool hit = f.get() != val;
 | 
						|
			f.set(val);
 | 
						|
			if (hit && field().dlg() != id)
 | 
						|
			{
 | 
						|
				f.on_hit();
 | 
						|
				if (t == RUNNING_CHECK)
 | 
						|
					f.check();
 | 
						|
			}
 | 
						|
		}
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
KEY TList_sheet::run()
 | 
						|
{
 | 
						|
  TArray_sheet sci(3, 3, -3, -3, _caption, _head);
 | 
						|
  sci.rows_array() = _data;
 | 
						|
 | 
						|
  _row = do_input();
 | 
						|
  sci.select(_row);
 | 
						|
  const KEY k = sci.run();
 | 
						|
 | 
						|
  switch (k)
 | 
						|
  {
 | 
						|
  case K_ENTER:
 | 
						|
    _row = (int)sci.selected();
 | 
						|
    do_output();
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
bool TList_sheet::check(CheckTime t)
 | 
						|
{                                       
 | 
						|
  _row = do_input();
 | 
						|
  bool passed = _row != -1;
 | 
						|
  if (passed) 
 | 
						|
    do_output(t);
 | 
						|
  else
 | 
						|
  {  
 | 
						|
    switch(field().check_type())
 | 
						|
    {
 | 
						|
    case CHECK_SEARCH: passed = true; break;
 | 
						|
    default: break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return passed;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TBrowse
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TBrowse::TBrowse(TEdit_field* f, TRelation* r, int key, const char* filter)
 | 
						|
       : TBrowse_button(f),
 | 
						|
         _relation(r), _cursor(new TCursor (r, "", key)),
 | 
						|
         _filter(filter), _secondary(false), _alt_browse(NULL),
 | 
						|
				 _custom_filter_handler(NULL)
 | 
						|
{
 | 
						|
	custom_cursor();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TBrowse::TBrowse(TEdit_field* f, TCursor* c)
 | 
						|
       : TBrowse_button(f),
 | 
						|
         _relation(NULL), _cursor(c), _secondary(false), _alt_browse(NULL),
 | 
						|
				 _custom_filter_handler(NULL)
 | 
						|
{
 | 
						|
	custom_cursor();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
TBrowse::~TBrowse()
 | 
						|
{
 | 
						|
  // Se e' stato usato il primo costruttore devo distruggere la relazione ed il cursore
 | 
						|
  if (_relation)
 | 
						|
  {
 | 
						|
    delete _cursor;
 | 
						|
    delete _relation;
 | 
						|
  }
 | 
						|
  if (_alt_browse)
 | 
						|
    delete _alt_browse;
 | 
						|
}
 | 
						|
 | 
						|
static bool descr_filter_handler(TMask_field& f, KEY k)
 | 
						|
{
 | 
						|
  if (k == K_SPACE)
 | 
						|
  {
 | 
						|
		TString expr;
 | 
						|
    if (!f.get().empty())          // Filtro attivato!
 | 
						|
		{
 | 
						|
			const short id = f.dlg()-500;
 | 
						|
			TString e = f.mask().get(id);  // Espressione regolare
 | 
						|
			e.strip("\"'");                // Tolgo caratteri che potrebbero dare problemi  
 | 
						|
			if (!e.blank())
 | 
						|
				expr << "(DESCR+DESCRAGG)" << "?=\"" << e << '"';
 | 
						|
			if (expr.empty())
 | 
						|
				f.reset();
 | 
						|
		}
 | 
						|
    ((TBrowse_sheet&) f.mask()).add_custom_filter(expr);
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::custom_cursor()
 | 
						|
{
 | 
						|
	TRelation * relation = _relation == NULL ? _cursor->relation() : _relation;
 | 
						|
	int logicnum =  relation->lfile().num();
 | 
						|
 | 
						|
	switch(logicnum)
 | 
						|
	{
 | 
						|
		case LF_ANAMAG :
 | 
						|
			if (_cursor->key() == 2 && ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2))
 | 
						|
			{
 | 
						|
				delete _cursor;
 | 
						|
				_cursor = new TSorted_cursor(relation, ANAMAG_DESCR "|" ANAMAG_DESCRAGG "[1,50]", "", 2);
 | 
						|
				set_custom_filter_handler(descr_filter_handler);
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			break;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::custom_display()
 | 
						|
{
 | 
						|
	switch(_cursor->file().num())
 | 
						|
	{
 | 
						|
	case LF_ANAMAG:
 | 
						|
		if (_cursor->key() == 2 && ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2))
 | 
						|
		{
 | 
						|
			TToken_string & it = (TToken_string &) items();
 | 
						|
			if (it.find(ANAMAG_DESCRAGG) < 0)
 | 
						|
			{
 | 
						|
				const char * s = it.get(0);
 | 
						|
				for (int i = 0; s && *s; s = it.get(++i))
 | 
						|
					if (strcmp(s, ANAMAG_DESCR) == 0)
 | 
						|
					{
 | 
						|
						add_display_field("Descrizione aggiuntiva@50", ANAMAG_DESCRAGG, i + 1);
 | 
						|
						break;
 | 
						|
					}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case LF_TABMOD:
 | 
						|
    {
 | 
						|
      _cursor->file().zero(); // Azzera il record corrente in modo da impostare "MOD"
 | 
						|
      const TString& mod =_cursor->curr().get("MOD");
 | 
						|
      const word cod = dongle().module_name2code(mod);
 | 
						|
      field().set_module(cod);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
	default:
 | 
						|
		break;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Certified 100%
 | 
						|
void TBrowse::parse_display(TScanner& scanner)
 | 
						|
{              
 | 
						|
  const char* s = scanner.string();
 | 
						|
  _head.add(dictionary_translate_header(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);
 | 
						|
  }
 | 
						|
  else            // Field on the mask
 | 
						|
  {                   
 | 
						|
    CHECKS(_inp_id.get_pos(s) < 0, "Duplicate input field ", s);
 | 
						|
    _inp_id.add(s);
 | 
						|
    if (scanner.popkey() == "SE") 
 | 
						|
      _inp_id << '@';       // Special FILTERing field
 | 
						|
    else 
 | 
						|
      scanner.push();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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);  
 | 
						|
  _secondary = false;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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().has_warning() && b.field().has_warning()) 
 | 
						|
      field().set_warning(b.field().get_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();
 | 
						|
 | 
						|
  int 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();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// Ritorna il numero di inputs senza contare quelli che funzionano solo da filtro
 | 
						|
int TBrowse::input_fields()
 | 
						|
{
 | 
						|
  int inp = 0;
 | 
						|
  FOR_EACH_TOKEN(_inp_id, fld)
 | 
						|
  {                                             
 | 
						|
    if (*fld && *fld != '"' && strchr(fld, '@') == NULL)
 | 
						|
    {
 | 
						|
      TMask_field& f = field(field().atodlg(fld));
 | 
						|
      if (f.active() && f.is_editable())
 | 
						|
        inp++;
 | 
						|
    }    
 | 
						|
  }
 | 
						|
  return inp;    
 | 
						|
}
 | 
						|
 | 
						|
const char* TBrowse::get_input_fields() const
 | 
						|
{
 | 
						|
  return _inp_id;
 | 
						|
}
 | 
						|
 | 
						|
const char* TBrowse::get_input_field_names() const
 | 
						|
{
 | 
						|
  return _inp_fn;
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::add_input_field(const char * id, const char * name, const int pos, bool select)
 | 
						|
{
 | 
						|
	TString strid(id) ;
 | 
						|
 | 
						|
	if (select)
 | 
						|
		strid << '@';
 | 
						|
	if (pos < 0 || pos >= _items.items())
 | 
						|
	{
 | 
						|
		_inp_id.add(strid);
 | 
						|
		_inp_fn.add(name);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_inp_id.insert_at(strid, pos);
 | 
						|
		_inp_fn.insert_at(name, pos);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::remove_display_field(const int pos)
 | 
						|
{
 | 
						|
	if (pos < 0)
 | 
						|
	{
 | 
						|
		_head.cut(0);
 | 
						|
		_items.cut(0);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_head.destroy(pos);
 | 
						|
		_items.destroy(pos);
 | 
						|
	}
 | 
						|
}
 | 
						|
void TBrowse::copy_input(const TBrowse * b)
 | 
						|
{
 | 
						|
	if (b)
 | 
						|
	{
 | 
						|
		_inp_id = b->_inp_id;
 | 
						|
		_inp_fn = b->_inp_fn;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::copy_display(const TBrowse* b)
 | 
						|
{
 | 
						|
	if (b)
 | 
						|
    b->get_display_fields(_head, _items);
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::copy_output(const TBrowse * b)
 | 
						|
{
 | 
						|
	if (b)
 | 
						|
	{
 | 
						|
		_out_id = b->_out_id;
 | 
						|
		_out_fn = b->_out_fn;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::add_display_field(const char * hd, const char * name, const int pos)
 | 
						|
{
 | 
						|
	if (pos < 0 || pos >= _items.items())
 | 
						|
	{
 | 
						|
		_head.add(dictionary_translate_header(hd));
 | 
						|
		_items.add(name);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_head.insert_at(dictionary_translate_header(hd), pos);
 | 
						|
		_items.insert_at(name, pos);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::remove_input_field(const int pos)
 | 
						|
{
 | 
						|
	if (pos < 0)
 | 
						|
	{
 | 
						|
		_inp_id.cut(0);
 | 
						|
		_inp_fn.cut(0);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_inp_id.destroy(pos);
 | 
						|
		_inp_fn.destroy(pos);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::add_output_field(const char * id, const char * name, const int pos)
 | 
						|
{
 | 
						|
	if (pos < 0 || pos >= _items.items())
 | 
						|
	{
 | 
						|
		_out_id.add(id);
 | 
						|
		_out_fn.add(name);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_out_id.insert_at(id, pos);
 | 
						|
		_out_fn.insert_at(name, pos);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::remove_output_field(const int pos)
 | 
						|
{
 | 
						|
	if (pos < 0)
 | 
						|
	{
 | 
						|
		_out_id.cut(0);
 | 
						|
		_out_fn.cut(0);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_out_id.destroy(pos);
 | 
						|
		_out_fn.destroy(pos);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char* TBrowse::get_output_fields() const
 | 
						|
{
 | 
						|
  return _out_id;
 | 
						|
}
 | 
						|
 | 
						|
const char* TBrowse::get_output_field_names() const
 | 
						|
{
 | 
						|
  return _out_fn;
 | 
						|
}
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @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 Indica se effettuare il filtro sulla selezione
 | 
						|
 | 
						|
  // @comm Questa funzione serve ai <c TCursor_sheet>
 | 
						|
{
 | 
						|
  int ne = 0;
 | 
						|
  if (_inp_id.empty()) 
 | 
						|
    return ne;
 | 
						|
 | 
						|
  _cursor->file(0).zero();  // was cur.zero() che non va bene per le tabelle di modulo
 | 
						|
  TRectype& cur = _cursor->curr();
 | 
						|
  TRectype filtrec(cur);
 | 
						|
 | 
						|
  _inp_id.restart();
 | 
						|
  _inp_fn.restart();
 | 
						|
 | 
						|
  TString val;                  // Value to output
 | 
						|
  bool tofilter = false;
 | 
						|
 | 
						|
  for (const char* fld = _inp_id.get(); fld; fld = _inp_id.get())
 | 
						|
  {
 | 
						|
    const TFieldref fldref(_inp_fn.get(), 0); // Output field
 | 
						|
 | 
						|
    if (*fld == '"')
 | 
						|
    {
 | 
						|
      val = (fld+1);
 | 
						|
      if (val.not_empty()) val.rtrim(1);
 | 
						|
      tofilter = filter;
 | 
						|
    } 
 | 
						|
    else
 | 
						|
    {
 | 
						|
      const TMask_field* campf = NULL;
 | 
						|
 | 
						|
      if (*fld == '-')
 | 
						|
      {
 | 
						|
        TSheet_field* sheet = field().mask().get_sheet();
 | 
						|
        if (sheet != NULL)
 | 
						|
        {
 | 
						|
          const short id = atoi(fld+1);
 | 
						|
          campf = &sheet->mask().field(id);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        const short id  = field().atodlg(fld);
 | 
						|
        campf = &field(id);
 | 
						|
      }
 | 
						|
 | 
						|
      if (campf != NULL)
 | 
						|
      {
 | 
						|
        const TMask_field& f = *campf;
 | 
						|
        val = f.get();
 | 
						|
            
 | 
						|
        switch (f.class_id())
 | 
						|
        {
 | 
						|
        case CLASS_REAL_FIELD:
 | 
						|
          // Cerco di allineare correttamente i campi interi salvati parzialmente su codtab
 | 
						|
          if (fldref.to() > 1 && f.size() > 1 && val.full() && 
 | 
						|
              ((TReal_field&)f).decimals() == 0 && fldref.name() == "CODTAB")
 | 
						|
          {
 | 
						|
            const int len = fldref.len(cur); 
 | 
						|
            if (f.size() == len && val.len() < len)
 | 
						|
              val.right_just(len);
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        case CLASS_DATE_FIELD:
 | 
						|
          if (f.right_justified())
 | 
						|
          {
 | 
						|
            const TDate d(val);
 | 
						|
            val = d.string(ANSI);
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        default:
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      
 | 
						|
        const bool filter_flag = strchr(fld, '@') != NULL;
 | 
						|
        tofilter = filter && filter_flag;
 | 
						|
        if (f.is_edit() && val.not_empty() && !filter_flag) 
 | 
						|
          ne++;          // Increment not empty fields count
 | 
						|
      }
 | 
						|
    }
 | 
						|
    fldref.write(val, *_cursor->relation());
 | 
						|
    if (tofilter)
 | 
						|
    {
 | 
						|
			const int len = fldref.len(cur);
 | 
						|
 | 
						|
      if (val.len() < len	&& cur.type(fldref.name()) == _alfafld)
 | 
						|
        val.rpad(len, '~');
 | 
						|
      fldref.write(val, filtrec);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!filter) 
 | 
						|
    return ne;
 | 
						|
 | 
						|
  TString work(_filter.size());
 | 
						|
  bool filter_update = false;
 | 
						|
  
 | 
						|
  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] == '#')
 | 
						|
      {
 | 
						|
				if (_filter[++i] == '-')
 | 
						|
				{
 | 
						|
					TString val;
 | 
						|
	        TSheet_field* sheet = field().mask().get_sheet();
 | 
						|
 | 
						|
		      if (sheet != NULL)
 | 
						|
			    {
 | 
						|
			     const short id = atoi(&_filter[++i]);
 | 
						|
			     
 | 
						|
					 val = sheet->mask().field(id).get();
 | 
						|
			   }
 | 
						|
					work << '"' << val << '"';
 | 
						|
			  }
 | 
						|
				else
 | 
						|
					work << '"' << field(atoi(&_filter[i])).get() << '"';
 | 
						|
        while (isspace(_filter[i])) i++;
 | 
						|
        while (isdigit(_filter[i])) i++;
 | 
						|
        i--;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        work << _filter[i];
 | 
						|
        if (_filter[i] == '-' && _filter[i + 1] == '>')
 | 
						|
          filter_update = true; 
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
	_cursor->relation()->mask2rel(field().mask());
 | 
						|
  _cursor->setfilter(work, filter_update);
 | 
						|
  _cursor->setregion(filtrec, filtrec);
 | 
						|
 | 
						|
  return ne;
 | 
						|
}
 | 
						|
 | 
						|
static TBit_array s_checked;
 | 
						|
static short s_checking = 0;
 | 
						|
 | 
						|
void TBrowse::do_output(CheckTime t)
 | 
						|
{                   
 | 
						|
  if (t == FINAL_CHECK) 
 | 
						|
    return;
 | 
						|
 | 
						|
  const bool master = s_checking == 0;  
 | 
						|
  if (master)  
 | 
						|
  {
 | 
						|
    s_checking = field().dlg();
 | 
						|
    s_checked.reset();
 | 
						|
    // Rendo intoccabili i campi del MIO output
 | 
						|
    for (const char* fld = _out_id.get(0); fld && *fld; fld = _out_id.get())
 | 
						|
    {
 | 
						|
      const short id = field().atodlg(fld);
 | 
						|
      s_checked.set(id);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  TString sum;
 | 
						|
  TToken_string flds(24, '+');
 | 
						|
  
 | 
						|
  const TRelation& relation = *_cursor->relation();
 | 
						|
  
 | 
						|
  TBit_array spotted;
 | 
						|
  
 | 
						|
  _out_fn.restart();   
 | 
						|
  const char* fld;
 | 
						|
  for (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();
 | 
						|
    
 | 
						|
    bool do_that = t != STARTING_CHECK || f.field() == NULL || (f.mask().mode() == MODE_INS && !f.in_key(0));
 | 
						|
    if (do_that && main_app().class_id() == CLASS_RELATION_APPLICATION)  
 | 
						|
    {
 | 
						|
      // Considera a parte l'inizializzazione delle transazioni!
 | 
						|
      // Non sovrascrivere con degli output campi che potrebbero essere riempiti dal .ini
 | 
						|
      if (!f.empty() && f.field() != NULL)
 | 
						|
      {
 | 
						|
        const TMask& m = f.mask();
 | 
						|
        if (!m.is_running() && m.get_sheet() == NULL) // Maschera principale chiusa
 | 
						|
        {
 | 
						|
          const TRelation_application& ra = (const TRelation_application&)main_app();
 | 
						|
          if (ra.is_transaction())
 | 
						|
            do_that = false;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (do_that)
 | 
						|
    {
 | 
						|
      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(relation);
 | 
						|
        }  
 | 
						|
      }
 | 
						|
                    
 | 
						|
      bool hit = false;
 | 
						|
      if (master)
 | 
						|
      {     
 | 
						|
        f.set(sum);
 | 
						|
        hit = id != s_checking; // Il mio handler viene fatto nella on_key
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {     
 | 
						|
        if (!s_checked[id])
 | 
						|
        {
 | 
						|
          f.set(sum);
 | 
						|
          s_checked.set(id);
 | 
						|
          hit = true;
 | 
						|
        }  
 | 
						|
      }
 | 
						|
      spotted.set(id, hit);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  for (fld = _out_id.get(0); fld && *fld; fld = _out_id.get())
 | 
						|
  {
 | 
						|
    const short id = field().atodlg(fld);
 | 
						|
    if (spotted[id])
 | 
						|
    {
 | 
						|
      TMask_field& f = field(id);
 | 
						|
      f.check();
 | 
						|
      f.on_hit();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (master)
 | 
						|
    s_checking = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TBrowse::do_clear(CheckTime t)
 | 
						|
{            
 | 
						|
  const bool master = s_checking == 0;  
 | 
						|
  if (master)  
 | 
						|
  {
 | 
						|
    s_checking = field().dlg();
 | 
						|
    s_checked.reset();
 | 
						|
    // Rendo intoccabili i campi del MIO input
 | 
						|
    for (const char* fld = _inp_id.get(0); fld && *fld; fld = _inp_id.get())
 | 
						|
    {         
 | 
						|
      if (isdigit(*fld))
 | 
						|
      {
 | 
						|
        const short id = field().atodlg(fld);
 | 
						|
        s_checked.set(id);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (TString16 fld = _out_id.get(0); fld.not_empty(); fld = _out_id.get())
 | 
						|
  {                      
 | 
						|
    const short id = field().atodlg(fld);
 | 
						|
    TMask_field& f = field(atoi(fld));
 | 
						|
    if (f.field() == NULL && field().dlg() != id &&
 | 
						|
        !s_checked[id] && _inp_id.get_pos(fld) < 0) 
 | 
						|
    {
 | 
						|
      f.reset();
 | 
						|
      s_checked.set(id);
 | 
						|
      f.on_hit();
 | 
						|
      f.check(t);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (master)  
 | 
						|
    s_checking = 0;  
 | 
						|
}
 | 
						|
 | 
						|
bool TBrowse::do_link(bool insert)
 | 
						|
{
 | 
						|
  bool ok = false;
 | 
						|
  TString app;
 | 
						|
  if (_insert.starts_with("MTB", true))
 | 
						|
    _cursor->file().get_relapp(app);
 | 
						|
  else
 | 
						|
    app = _insert.mid(1);
 | 
						|
  if (app.find('#') >=  0)
 | 
						|
  {
 | 
						|
    const TString w(app);
 | 
						|
    app = "";
 | 
						|
    for (const char* f = w; *f; f++)
 | 
						|
    {
 | 
						|
      if (*f == '#') 
 | 
						|
      {
 | 
						|
        const int id = atoi(++f);
 | 
						|
        app << field(id).get();
 | 
						|
        while (isspace(*f)) ++f;
 | 
						|
        while (isdigit(*f)) ++f; 
 | 
						|
        if (*f)
 | 
						|
          app << ' ' << *f;
 | 
						|
        else 
 | 
						|
          break;
 | 
						|
      }            
 | 
						|
      else
 | 
						|
        app << *f;
 | 
						|
    }
 | 
						|
  } 
 | 
						|
  
 | 
						|
  TFilename msg; msg.temp("msg");
 | 
						|
  app << " /i" << msg;
 | 
						|
 | 
						|
  if (insert)
 | 
						|
  {
 | 
						|
    TConfig ini(msg, "Transaction");
 | 
						|
    ini.set("Action", TRANSACTION_RUN);
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {  
 | 
						|
    TConfig ini(msg, "Transaction");
 | 
						|
    ini.set("Action", TRANSACTION_LINK);
 | 
						|
 | 
						|
    TString8 paragraph; paragraph << _cursor->file().num();
 | 
						|
    ini.set_paragraph(paragraph);
 | 
						|
 | 
						|
    // Uso sempre la chiave 1 per collegarmi agli altri programmi
 | 
						|
    const TRelation& rel = *_cursor->relation();
 | 
						|
    const RecDes& recd = rel.curr().rec_des(); // Descrizione del record della testata
 | 
						|
    const KeyDes& kd = recd.Ky[0];             // Elenco dei campi della chiave 1
 | 
						|
    TString inp_val;
 | 
						|
    for (int i = 0; i < kd.NkFields; i++)
 | 
						|
    {                        
 | 
						|
      const int nf = kd.FieldSeq[i] % MaxFields;
 | 
						|
      const RecFieldDes& rf = recd.Fd[nf];  
 | 
						|
      const TFieldref fldref(rf.Name, 0);
 | 
						|
      inp_val = fldref.read(rel);
 | 
						|
      fldref.write(ini, paragraph, inp_val);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  TExternal_app a(app);
 | 
						|
  a.run();
 | 
						|
  field().mask().set_focus();
 | 
						|
 | 
						|
  if (msg.not_empty())
 | 
						|
  {
 | 
						|
    TConfig ini(msg, "Transaction");
 | 
						|
    _rec = ini.get_long("Record");
 | 
						|
    if (_rec > 0 || !insert)   // Modifica o cancellazione
 | 
						|
      _cursor->update();       // Forza ricalcolo cursore
 | 
						|
    if (_rec >= 0)
 | 
						|
    {
 | 
						|
      _cursor->file().readat(_rec);
 | 
						|
      ok = _cursor->ok();
 | 
						|
      if (ok) 
 | 
						|
      {
 | 
						|
        rec_cache(_cursor->file().num()).notify_change();  // Svuota eventule cache
 | 
						|
        do_output();
 | 
						|
      }    
 | 
						|
    }
 | 
						|
    ::remove(msg);
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TToken_string& TBrowse::create_siblings(TToken_string& siblings) const
 | 
						|
{
 | 
						|
  siblings = "";                      // Azzera la lista dei campi associati
 | 
						|
  
 | 
						|
  TBit_array key(4);                  // Elenco delle chiavi gia' utilizzate
 | 
						|
  key.set(_cursor->key());
 | 
						|
 | 
						|
  TString fn;                         // Nome campo
 | 
						|
  
 | 
						|
  // Scorre la lista dei campi di output
 | 
						|
  int n = 0;  
 | 
						|
  TToken_string& outid = (TToken_string&)_out_id;
 | 
						|
  for (const char* i = outid.get(0); i; i = outid.get(), n++)
 | 
						|
  {
 | 
						|
    const short id = field().atodlg(i);
 | 
						|
    const TEditable_field& f = field(id);
 | 
						|
    if (!f.active() || !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 == field().dlg()))      
 | 
						|
    {
 | 
						|
      _out_fn.get(n, fn);                     // Legge nome del campo su file          
 | 
						|
      int pos = ((TToken_string&)_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 = ((TToken_string&)_items).get_pos(fn);           // ... ritenta senza parentesi
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (pos >= 0)
 | 
						|
      {
 | 
						|
        siblings.add(id);
 | 
						|
        TString80 h; _head.get(pos, h); 
 | 
						|
        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()
 | 
						|
{    
 | 
						|
  const TString& val = field().get();
 | 
						|
 | 
						|
  if (val.starts_with("*"))
 | 
						|
  {
 | 
						|
    TFuzzy_browse fb(&field(), cursor()->key());
 | 
						|
    const KEY k = fb.run();
 | 
						|
    if (k == K_ENTER)
 | 
						|
    {
 | 
						|
      do_input(true);
 | 
						|
      _cursor->read(_isgteq);
 | 
						|
      do_output();
 | 
						|
    }
 | 
						|
    return k;
 | 
						|
  } else
 | 
						|
  if (val.starts_with("%") && _alt_browse)
 | 
						|
  {
 | 
						|
    const KEY k = _alt_browse->run();
 | 
						|
    if (k == K_ENTER)
 | 
						|
    {
 | 
						|
      do_input(true);
 | 
						|
      _cursor->read(_isgteq);
 | 
						|
      do_output();
 | 
						|
    }
 | 
						|
    return k;
 | 
						|
  }
 | 
						|
 | 
						|
  begin_wait();
 | 
						|
  
 | 
						|
  do_input(true);
 | 
						|
  _cursor->read(_isgteq);
 | 
						|
 | 
						|
  TString caption = _cursor->file().description();
 | 
						|
  if (caption.blank()) 
 | 
						|
    caption = TR("Selezione");
 | 
						|
  
 | 
						|
  KEY k = K_ESC;
 | 
						|
  long selected = 0;
 | 
						|
 | 
						|
  TToken_string siblings, vals; 
 | 
						|
  create_siblings(siblings);                            
 | 
						|
  
 | 
						|
  {
 | 
						|
    byte buttons = 0;
 | 
						|
    if (_insert.not_empty())
 | 
						|
    {   
 | 
						|
      // Mette il bottone di gestione, a meno che ...   
 | 
						|
      if (_cursor->items() == 0) 
 | 
						|
        buttons = 2; // Non mette il bottone collega se non ci sono elementi
 | 
						|
      else 
 | 
						|
        buttons = 3; 
 | 
						|
    
 | 
						|
      if (_insert[0] == 'M' || _insert[0] == 'R')
 | 
						|
      {          
 | 
						|
        const TString& maskname = field().mask().source_file();
 | 
						|
        if (maskname.mid(2,2).compare("tb", 2, true) == 0 && field().in_key(0))
 | 
						|
        {
 | 
						|
          const char* tabname = _cursor->file().name();
 | 
						|
          if (maskname.mid(4, 3).compare(tabname, 3, true) == 0) 
 | 
						|
            buttons = 0;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }  
 | 
						|
  
 | 
						|
    for (const char* i = _inp_id.get(0); i; i = _inp_id.get())
 | 
						|
    {            
 | 
						|
      if (*i != '\0' && *i != '"' && strchr(i, '@') == NULL)
 | 
						|
      {
 | 
						|
        const short id = field().atodlg(i);
 | 
						|
        const TEditable_field& f = field(id);
 | 
						|
        if (f.active() && f.is_editable()) 
 | 
						|
        {           
 | 
						|
          vals.add(i);
 | 
						|
          vals.add(f.get());               
 | 
						|
          vals.add((int)f.dirty());
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }  
 | 
						|
  
 | 
						|
    end_wait();
 | 
						|
 | 
						|
    TBrowse_sheet s(_cursor, _items, caption, _head, buttons, field(), siblings, _custom_filter_handler);
 | 
						|
 | 
						|
    k = s.run();
 | 
						|
    selected = s.selected();
 | 
						|
  }
 | 
						|
 | 
						|
  switch (k)
 | 
						|
  {        
 | 
						|
  case K_ESC:
 | 
						|
  case K_QUIT:
 | 
						|
    break;
 | 
						|
  case K_CTRL+'G':    
 | 
						|
    *_cursor = selected;
 | 
						|
    k = do_link(false) ? K_ENTER : K_ESC;
 | 
						|
    break;  
 | 
						|
  case K_INS:
 | 
						|
    k = do_link(true) ? K_ENTER : K_ESC;
 | 
						|
    break;
 | 
						|
  case K_ENTER:
 | 
						|
    *_cursor = selected;
 | 
						|
    do_output();
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    {
 | 
						|
      for (const char* i = vals.get(0); i && *i; i = vals.get())
 | 
						|
      {
 | 
						|
        const short id = field().atodlg(i);
 | 
						|
        TEditable_field& f = field(id);
 | 
						|
        f.set(vals.get());
 | 
						|
        f.set_dirty(vals.get_int());
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (k >= K_CTRL) // Scatta la ricerca su di una chiave alternativa
 | 
						|
    {
 | 
						|
      TMask& m = field().mask();                          
 | 
						|
      const int tag = k - K_CTRL - K_F1;
 | 
						|
      const short id = siblings.get_int(tag * 2);
 | 
						|
      TEdit_field& ef = m.efield(id);
 | 
						|
      ef.set_focus();
 | 
						|
      k = K_F9;
 | 
						|
      if (m.is_running())
 | 
						|
        m.send_key(k, id, &ef); //m.send_key(k, id);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  }
 | 
						|
    
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
void TBrowse::set_cursor(TCursor* c)
 | 
						|
{
 | 
						|
	if (_cursor != NULL)
 | 
						|
		delete _cursor;
 | 
						|
	_cursor = c ;
 | 
						|
}
 | 
						|
 | 
						|
bool TBrowse::check(CheckTime t)
 | 
						|
{
 | 
						|
  bool passed = true;
 | 
						|
 | 
						|
  if (_secondary == true && t != RUNNING_CHECK)
 | 
						|
    return true;
 | 
						|
 | 
						|
  CheckType chk = field().check_type();
 | 
						|
 | 
						|
  // Se ho la ricerca alternativa ed il campo comincia per % ...
 | 
						|
  if (t == RUNNING_CHECK)
 | 
						|
  {
 | 
						|
    const TString& magic = field().get();
 | 
						|
    if (magic[0] == '*' && cursor()->key() > 1)
 | 
						|
    {
 | 
						|
      TFuzzy_browse fb(&field(), cursor()->key());
 | 
						|
      if (fb.check(t))
 | 
						|
      {
 | 
						|
        if (chk == CHECK_NONE) // Se trovo la chiave forzo gli output (RAGSOC in righe prima nota)
 | 
						|
          chk = CHECK_NORMAL;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        return false;
 | 
						|
    } else
 | 
						|
    if (magic[0] =='%' && _alt_browse != NULL)
 | 
						|
    {
 | 
						|
      if (_alt_browse->check(t))
 | 
						|
      {
 | 
						|
        if (chk == CHECK_NONE) // Se trovo la chiave forzo gli output (RAGSOC in righe prima nota)
 | 
						|
          chk = CHECK_NORMAL;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (chk != CHECK_NONE)
 | 
						|
  {
 | 
						|
    const TMaskmode mode = (TMaskmode)field().mask().mode();
 | 
						|
    if (chk == CHECK_REQUIRED && (t == STARTING_CHECK || mode == MODE_QUERY))
 | 
						|
      chk = CHECK_NORMAL;
 | 
						|
    
 | 
						|
    const int ne = do_input(true);
 | 
						|
    if (ne || chk == CHECK_REQUIRED)
 | 
						|
    {               
 | 
						|
      passed = _cursor->test() == NOERR;
 | 
						|
 | 
						|
      if (t != FINAL_CHECK)
 | 
						|
      {
 | 
						|
        if (passed)
 | 
						|
        {           
 | 
						|
          _cursor->repos();
 | 
						|
          do_output(t);
 | 
						|
					if (t == STARTING_CHECK && field().dirty() > 1)
 | 
						|
						field().set_dirty(true);
 | 
						|
        }
 | 
						|
        else 
 | 
						|
        {    
 | 
						|
          if (chk == CHECK_SEARCH)
 | 
						|
          {   
 | 
						|
            passed = true;
 | 
						|
          }
 | 
						|
          else
 | 
						|
          {
 | 
						|
            do_clear(t);
 | 
						|
            if (!field().mask().query_mode() && field().check_enabled())
 | 
						|
              field().set_dirty(3);
 | 
						|
          }    
 | 
						|
        }  
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        if (chk == CHECK_SEARCH)
 | 
						|
          passed = true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {         
 | 
						|
      if (chk == CHECK_SEARCH)
 | 
						|
        passed = true;
 | 
						|
      else
 | 
						|
      {  
 | 
						|
        if (t != FINAL_CHECK) 
 | 
						|
          do_clear(t);
 | 
						|
      }  
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  return passed;
 | 
						|
}
 | 
						|
 | 
						|
bool TBrowse::empty_check()
 | 
						|
{
 | 
						|
  if (field().mask().query_mode() || field().check_type() != CHECK_REQUIRED)
 | 
						|
    return true;
 | 
						|
  else
 | 
						|
    return do_input() > 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TBrowse::set_alt_browse(int altkey)
 | 
						|
{
 | 
						|
  if (_alt_browse)
 | 
						|
    delete _alt_browse;
 | 
						|
  if (altkey > 2)
 | 
						|
    _alt_browse = new TAlternative_browse(&field(), altkey);
 | 
						|
  return altkey > 2;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TFile_select
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TFile_select::TFile_select(TEdit_field* ef, const char* filter)
 | 
						|
: TBrowse_button(ef), _filter(filter)
 | 
						|
{ }
 | 
						|
 | 
						|
void TFile_select::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
 | 
						|
void TFile_select::parse_output(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
          
 | 
						|
KEY TFile_select::run()
 | 
						|
{
 | 
						|
  TFilename path;
 | 
						|
  path = field().get();
 | 
						|
  if (path.full() && _filter.find('.') > 0 && !_filter.ends_with(".*"))
 | 
						|
    path.ext(_filter.ext());
 | 
						|
 | 
						|
  FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(path, &fs);
 | 
						|
  
 | 
						|
  bool good = xvt_dm_post_file_open(&fs, field().prompt()) == FL_OK;
 | 
						|
  if (good)
 | 
						|
  {
 | 
						|
    xvt_fsys_convert_fspec_to_str(&fs, path.get_buffer(), path.size());
 | 
						|
    good = _filter.blank() || xvt_str_match(path.name(), _filter, false);
 | 
						|
    if (good)
 | 
						|
      field().set(path);
 | 
						|
    else
 | 
						|
      field().error_box(FR("Il nome del file non corrisponde a %s"), _filter.get_buffer());
 | 
						|
  }
 | 
						|
  return good ? K_ENTER : K_ESC;
 | 
						|
}
 | 
						|
 | 
						|
bool TFile_select::check(CheckTime ct)
 | 
						|
{
 | 
						|
  const TFilename name = field().get();
 | 
						|
  if (ct != STARTING_CHECK && name.empty() && 
 | 
						|
      field().check_type() == CHECK_REQUIRED)
 | 
						|
    return false;
 | 
						|
  bool ok = _filter.empty() || xvt_str_match(name, _filter, false);
 | 
						|
  if (ok && field().roman())  // Must exist
 | 
						|
    ok = name.exist();
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TDir_select
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TDir_select::TDir_select(TEdit_field* ef) : TBrowse_button(ef)
 | 
						|
{ }
 | 
						|
 | 
						|
void TDir_select::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
 | 
						|
void TDir_select::parse_output(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
          
 | 
						|
KEY TDir_select::run()
 | 
						|
{
 | 
						|
  DIRECTORY savedir;
 | 
						|
  xvt_fsys_get_dir(&savedir);
 | 
						|
 | 
						|
	DIRECTORY dir;
 | 
						|
	xvt_fsys_convert_str_to_dir(field().get(), &dir);
 | 
						|
  bool good = xvt_dm_post_dir_sel(&dir) == FL_OK;
 | 
						|
  xvt_fsys_set_dir(&savedir);
 | 
						|
 | 
						|
  if (good)
 | 
						|
  {
 | 
						|
    TFilename path;
 | 
						|
    xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size());
 | 
						|
    field().set(path);
 | 
						|
  }
 | 
						|
  return good ? K_ENTER : K_ESC;
 | 
						|
}
 | 
						|
 | 
						|
bool TDir_select::check(CheckTime ct)
 | 
						|
{
 | 
						|
  const TFilename name = field().get();
 | 
						|
  if (ct != STARTING_CHECK && name.empty() && 
 | 
						|
      field().check_type() == CHECK_REQUIRED)
 | 
						|
    return false;
 | 
						|
  bool ok = true;
 | 
						|
  if (field().roman())  // Must exist
 | 
						|
    ok = name.exist();
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TProfile_select
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TProfile_select::TProfile_select(TEdit_field* ef)
 | 
						|
: TBrowse_button(ef)
 | 
						|
{ }
 | 
						|
 | 
						|
void TProfile_select::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
 | 
						|
void TProfile_select::parse_output(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN int get_profile_desc(TConfig& cfg, void* jolly)
 | 
						|
{
 | 
						|
  const int num = atoi(cfg.get_paragraph());
 | 
						|
  if (num > 0)
 | 
						|
  {
 | 
						|
    TString_array& p = *(TString_array*)jolly;
 | 
						|
    TToken_string* str = new TToken_string;
 | 
						|
    str->format("%4d", num);
 | 
						|
    str->add(cfg.get("Description"));
 | 
						|
    p.add(str);
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
int TProfile_select::get_descriptions(TString_array& a) const
 | 
						|
{
 | 
						|
  TFilename profname; 
 | 
						|
  field().mask().make_profile_name(profname);
 | 
						|
  TConfig prof(profname);
 | 
						|
  a.destroy();
 | 
						|
  prof.for_each_paragraph(get_profile_desc, &a);
 | 
						|
  a.sort();
 | 
						|
  return a.items();
 | 
						|
}
 | 
						|
          
 | 
						|
KEY TProfile_select::run()
 | 
						|
{                 
 | 
						|
  TArray_sheet p(3, 3, -3, -3, TR("Profili"), HR("Codice@6R|Descrizione@60"), 0x6, 2);
 | 
						|
  const short id = DLG_USER+1;
 | 
						|
  TEdit_field& prompt = p.add_string(id, 0, PR("Salva con nome "), 1, 0, 60);
 | 
						|
  p.add_button(DLG_SAVEREC, PR("~Registra"), K_CTRL+'r', TOOL_SAVEREC);
 | 
						|
  prompt.set(field().get());
 | 
						|
  
 | 
						|
  TMask& m = field().mask();
 | 
						|
  TFilename profname; m.make_profile_name(profname);
 | 
						|
  
 | 
						|
  bool running = true;
 | 
						|
  KEY key;
 | 
						|
  while (running)
 | 
						|
  {
 | 
						|
    p.destroy();  
 | 
						|
    TString_array& a = p.rows_array(); 
 | 
						|
    get_descriptions(a);
 | 
						|
    p.field(DLG_SAVEREC).enable(a.items()>0);
 | 
						|
    FOR_EACH_ARRAY_ROW_BACK(a, r, row)
 | 
						|
      if (field().get() == row->get(1)) break;
 | 
						|
    if (r)
 | 
						|
      p.select(r);
 | 
						|
  
 | 
						|
    key = p.run();
 | 
						|
    switch(key)
 | 
						|
    {       
 | 
						|
    case K_ENTER:      
 | 
						|
      { 
 | 
						|
        const int num = p.row().get_int(0);
 | 
						|
        TString16 para; para << m.load_profile(num);
 | 
						|
        prompt.set(p.row().get(1));
 | 
						|
        running = false;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case K_CTRL+'r':             
 | 
						|
      {    
 | 
						|
        const TString& name = p.get(id);
 | 
						|
        FOR_EACH_ARRAY_ROW_BACK(a, r, row)
 | 
						|
          if (r != p.selected() && name == row->get(1)) break;
 | 
						|
        if (r < 0)
 | 
						|
        {
 | 
						|
          const int num = p.row().get_int(0);
 | 
						|
          m.save_profile(num, name);
 | 
						|
          running = false;
 | 
						|
        }
 | 
						|
        else
 | 
						|
          error_box("Esiste gia' un profilo di nome\n%s", 
 | 
						|
                    (const char*)name);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case K_INS:
 | 
						|
      {
 | 
						|
        const TString& name = p.get(id);
 | 
						|
        if (!name.blank())
 | 
						|
        {
 | 
						|
          FOR_EACH_ARRAY_ROW_BACK(a, r, row)
 | 
						|
            if (name == row->get(1)) break;
 | 
						|
          if (r < 0)  
 | 
						|
          {
 | 
						|
            TString16 para; para << m.save_profile(-1, name);
 | 
						|
            field().set(name);
 | 
						|
            running = false;
 | 
						|
          }
 | 
						|
          else
 | 
						|
            error_box("Esiste gia' un profilo di nome\n%s", 
 | 
						|
                      (const char*)name);
 | 
						|
        }
 | 
						|
        else
 | 
						|
          error_box("E' necessario dare un nome al profilo");
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case K_DEL:
 | 
						|
      {                                 
 | 
						|
        TString16 para; para << p.row().get_int(0);
 | 
						|
        const TString desc = p.row().get(1);
 | 
						|
        TConfig prof(profname, para);
 | 
						|
        if (yesno_box("Confermare la cancellazione del profilo %s\n%s", 
 | 
						|
                      (const char*)para, (const char*)desc))
 | 
						|
          prof.remove_all();
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      running = false;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  field().set(prompt.get());
 | 
						|
  return key;
 | 
						|
}
 | 
						|
 | 
						|
bool TProfile_select::check(CheckTime ct)
 | 
						|
{            
 | 
						|
  switch (ct)
 | 
						|
  {
 | 
						|
  case STARTING_CHECK:
 | 
						|
    {     
 | 
						|
      TMask& m = field().mask();
 | 
						|
      TFilename name; m.make_profile_name(name);
 | 
						|
      TString16 para; para << m.load_profile();
 | 
						|
      TConfig ini(name, para);
 | 
						|
      field().set(ini.get("Description"));
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case RUNNING_CHECK:
 | 
						|
    if (!field().empty())
 | 
						|
    { 
 | 
						|
      const TString& name = field().get();
 | 
						|
      TString_array a;
 | 
						|
      get_descriptions(a);               
 | 
						|
      FOR_EACH_ARRAY_ROW_BACK(a, r, row)      
 | 
						|
      {
 | 
						|
        if (name == row->get(1))
 | 
						|
        {       
 | 
						|
          field().mask().load_profile(row->get_int(0));
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (r < 0)  
 | 
						|
        return field().error_box("Profilo inesistente");
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case FINAL_CHECK:
 | 
						|
    if (!field().active())
 | 
						|
    {
 | 
						|
      TMask& m = field().mask();
 | 
						|
      m.save_profile();
 | 
						|
    }
 | 
						|
    break;  
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TReport_select
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TReport_select::TReport_select(TEdit_field* ef, const char* classe)
 | 
						|
: TBrowse_button(ef), _classe(classe)
 | 
						|
{ }
 | 
						|
 | 
						|
void TReport_select::parse_input(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
 | 
						|
void TReport_select::parse_output(TScanner& scanner)
 | 
						|
{
 | 
						|
  scanner.pop();
 | 
						|
}
 | 
						|
          
 | 
						|
KEY TReport_select::run()
 | 
						|
{
 | 
						|
  TFilename path = field().get();
 | 
						|
  if (select_custom_file(path, "rep", _classe))
 | 
						|
  {
 | 
						|
    path = path.name();
 | 
						|
    path.ext("");
 | 
						|
    field().set(path);
 | 
						|
  }
 | 
						|
 | 
						|
  return path.not_empty() ? K_ENTER : K_ESC;
 | 
						|
}
 | 
						|
 | 
						|
bool TReport_select::check(CheckTime ct)
 | 
						|
{
 | 
						|
  TFilename name = field().get();
 | 
						|
  if (ct != STARTING_CHECK && name.empty() && 
 | 
						|
      field().check_type() == CHECK_REQUIRED)
 | 
						|
    return false;
 | 
						|
 | 
						|
  bool ok = true;
 | 
						|
  if (field().roman())  // Must exist
 | 
						|
    ok = name.custom_path();
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
//   TFuzzy_browse
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
static TFuzzy_browse* _curr_fbrowse = NULL;
 | 
						|
 | 
						|
 | 
						|
TCursor& TFuzzy_browse::cursor()
 | 
						|
{
 | 
						|
  TBrowse& b = *field().browse();
 | 
						|
  TCursor& c = *b.cursor();
 | 
						|
 | 
						|
  if (_altfld.empty())
 | 
						|
  {
 | 
						|
    const RecDes& rd = c.curr().rec_des();
 | 
						|
    CHECKD(_altkey > 0 && _altkey <= rd.NKeys, "Invalid browse key ", _altkey);
 | 
						|
    const KeyDes& kd = rd.Ky[_altkey-1];
 | 
						|
    const int mf = kd.FieldSeq[kd.NkFields-1] % MaxFields;
 | 
						|
    _altfld = rd.Fd[mf].Name;
 | 
						|
 | 
						|
    _outfld = "RAGSOC";
 | 
						|
    TToken_string outfields = b.get_output_fields();
 | 
						|
    const int outpos = outfields.get_pos(field().dlg());
 | 
						|
    if (outpos >= 0)
 | 
						|
    {
 | 
						|
      outfields = b.get_output_field_names();
 | 
						|
      outfields.get(outpos, _outfld);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  return c;
 | 
						|
}
 | 
						|
 | 
						|
static void clean_string(TString& str)
 | 
						|
{
 | 
						|
  char* d = str.get_buffer();
 | 
						|
  for (const char* s = d; *s; s++)
 | 
						|
    if (*s < '\0' || isalnum(*s)) *d++ = *s;
 | 
						|
  *d = '\0';
 | 
						|
  str.upper();
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TFuzzy_browse::find_magic(const TString& magic_val, double& best)
 | 
						|
{
 | 
						|
  const TBrowse& b = *field().browse();
 | 
						|
  TCursor& c = cursor();
 | 
						|
 | 
						|
  c = 0L;
 | 
						|
  TRecnotype recno = -1;
 | 
						|
  TRectype& curr =  c.curr();
 | 
						|
 | 
						|
  curr.put(_altfld, magic_val);
 | 
						|
  recno = c.read();
 | 
						|
  if (recno >= 0 && curr.get(_altfld).starts_with(magic_val))
 | 
						|
    return recno;
 | 
						|
 | 
						|
  recno = -1;
 | 
						|
  best = 0.66;
 | 
						|
 | 
						|
  const int testlen = magic_val.len()+1;
 | 
						|
  if (testlen > 3)
 | 
						|
  {
 | 
						|
    for (c = 0L; c.ok(); ++c)
 | 
						|
    {
 | 
						|
      TString80 val = curr.get(_altfld);
 | 
						|
      clean_string(val);
 | 
						|
 | 
						|
      for (int i = val.find(magic_val[0], 0); i >= 0; i = val.find(magic_val[0], i+1))
 | 
						|
      {
 | 
						|
        double n = xvt_str_fuzzy_compare(val.mid(i, testlen), magic_val);
 | 
						|
        n -= i*0.01;
 | 
						|
        if (n > best)
 | 
						|
        {
 | 
						|
          best = n;
 | 
						|
          recno = c.pos();
 | 
						|
          if (n >= 1.0)
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (recno >= 0)
 | 
						|
    c = recno;
 | 
						|
  else
 | 
						|
    best = 0;
 | 
						|
  return recno;
 | 
						|
}
 | 
						|
 | 
						|
TRecnotype TFuzzy_browse::find(const TString& raw_val)
 | 
						|
{
 | 
						|
  TString80 magic_val = raw_val;
 | 
						|
  clean_string(magic_val);
 | 
						|
 | 
						|
  double best = 0;
 | 
						|
  TRecnotype recno = find_magic(magic_val, best);
 | 
						|
 | 
						|
  if (best < 0.8 && raw_val.find(' ') > 0)
 | 
						|
  {
 | 
						|
    magic_val = raw_val;
 | 
						|
    magic_val.strip_double_spaces();
 | 
						|
    const int spc = magic_val.find(' ');
 | 
						|
    if (spc > 0)
 | 
						|
    {
 | 
						|
      const TString& left = magic_val.left(spc);
 | 
						|
      const TString& right = magic_val.mid(spc+1);
 | 
						|
      magic_val.cut(0) << right << ' ' << left; 
 | 
						|
      clean_string(magic_val);
 | 
						|
      double altbest = 0;
 | 
						|
      const TRecnotype altrecno = find_magic(magic_val, altbest);
 | 
						|
      if (altbest > best)
 | 
						|
      {
 | 
						|
        best = altbest;
 | 
						|
        recno = altrecno;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return recno;
 | 
						|
}
 | 
						|
 | 
						|
bool TFuzzy_browse::check(CheckTime /*t*/) 
 | 
						|
{ 
 | 
						|
  const TRecnotype recno = find(field().get());
 | 
						|
  if (recno >= 0)
 | 
						|
  {
 | 
						|
    field().set(cursor().curr().get(_outfld));
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  return run() == K_ENTER;
 | 
						|
}
 | 
						|
 | 
						|
static bool fuzzy_code_handler(TMask_field& f, KEY k)
 | 
						|
{
 | 
						|
  if (k == K_F2)
 | 
						|
  {
 | 
						|
    f.reset();
 | 
						|
    k = K_SPACE;
 | 
						|
  }
 | 
						|
  if (k == K_SPACE || k == K_TAB)
 | 
						|
  {
 | 
						|
    const TString& str = ((TEdit_field&)f).get_window_data();
 | 
						|
    const TRecnotype pos = _curr_fbrowse->find(str);
 | 
						|
    if (pos >= 0)
 | 
						|
    {
 | 
						|
      TSheet& s = (TSheet&)f.mask();
 | 
						|
      if (k == K_TAB)
 | 
						|
      {
 | 
						|
        f.set(s.row(pos).get(0));
 | 
						|
        s.post_select(pos);
 | 
						|
      }
 | 
						|
      else
 | 
						|
        s.select(pos);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
KEY TFuzzy_browse::run()
 | 
						|
{
 | 
						|
  const TBrowse& b = *field().browse();
 | 
						|
  TCursor& c = cursor();
 | 
						|
 | 
						|
  TString caption = c.file().description();
 | 
						|
  if (caption.blank()) 
 | 
						|
    caption = TR("Selezione");
 | 
						|
 | 
						|
  TToken_string fields, head;
 | 
						|
  b.get_display_fields(head, fields);
 | 
						|
 | 
						|
  TCursor_sheet sheet(&c, fields, caption, head, 0, 2);
 | 
						|
  TEdit_field& e = sheet.add_string(field().dlg(), 0, field().prompt(), 1, 1, field().size(), "U");
 | 
						|
  e.set_handler(fuzzy_code_handler);
 | 
						|
 | 
						|
  _curr_fbrowse = this;
 | 
						|
 | 
						|
  TString80 val = field().get();
 | 
						|
  val.strip("*");
 | 
						|
  e.set(val);
 | 
						|
  e.on_key(K_SPACE);
 | 
						|
  sheet.first_focus(e.dlg());
 | 
						|
  const KEY k = sheet.run();
 | 
						|
  _curr_fbrowse = NULL;
 | 
						|
  
 | 
						|
  if (k == K_ENTER)
 | 
						|
  {
 | 
						|
    c = sheet.selected();
 | 
						|
    const TFieldref fr(_outfld, 0);
 | 
						|
    field().set(fr.read(*c.relation()));
 | 
						|
  }
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
TFuzzy_browse::TFuzzy_browse(TEdit_field* ef, int altkey) : TBrowse_button(ef), _altkey(altkey)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
//   TAlternative_browse
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
static TBit_array _alternative_bits;
 | 
						|
 | 
						|
static bool alternative_filter(const TRelation* rel)
 | 
						|
{
 | 
						|
  const TRecnotype recno = rel->file().recno();
 | 
						|
  return _alternative_bits[recno];
 | 
						|
}
 | 
						|
 | 
						|
TCursor& TAlternative_browse::cursor()
 | 
						|
{
 | 
						|
  if (_cursor == NULL)
 | 
						|
  {
 | 
						|
    TBrowse& b = *field().browse();
 | 
						|
    TCursor& c = *b.cursor();
 | 
						|
 | 
						|
    const RecDes& rd = c.curr().rec_des();
 | 
						|
    const KeyDes& kd = rd.Ky[_altkey-1];
 | 
						|
    const int mf = kd.FieldSeq[kd.NkFields-1] % MaxFields;
 | 
						|
    _altfld = rd.Fd[mf].Name;
 | 
						|
 | 
						|
     _outfld = "RAGSOC";
 | 
						|
    TToken_string outfields = b.get_output_fields();
 | 
						|
    const int outpos = outfields.get_pos(field().dlg());
 | 
						|
    if (outpos >= 0)
 | 
						|
    {
 | 
						|
      outfields = b.get_output_field_names();
 | 
						|
      outfields.get(outpos, _outfld);
 | 
						|
    }
 | 
						|
 | 
						|
    _cursor = new TCursor(c.relation(), "", _altkey);
 | 
						|
    _alternative_bits.reset();
 | 
						|
    const TRecnotype old = c.pos();
 | 
						|
    for (c = 0L; c.ok(); ++c)
 | 
						|
    {
 | 
						|
      if (c.curr().get(_altfld).full())
 | 
						|
        _alternative_bits.set(c.file().recno());
 | 
						|
    }
 | 
						|
    _cursor->set_filterfunction(alternative_filter);
 | 
						|
    _cursor->items();
 | 
						|
    _cursor->freeze();
 | 
						|
    c = old;
 | 
						|
  }
 | 
						|
  return *_cursor;
 | 
						|
}
 | 
						|
 | 
						|
static bool alternative_code_handler(TMask_field& f, KEY k)
 | 
						|
{
 | 
						|
  if (k == K_F2)
 | 
						|
  {
 | 
						|
    f.reset();
 | 
						|
    k = K_SPACE;
 | 
						|
  }
 | 
						|
  if (k == K_SPACE || k == K_TAB)
 | 
						|
  {
 | 
						|
    const TString& str = ((TEdit_field&)f).get_window_data();
 | 
						|
    const TRecnotype pos = _curr_fbrowse->find(str);
 | 
						|
    if (pos >= 0)
 | 
						|
    {
 | 
						|
      TSheet& s = (TSheet&)f.mask();
 | 
						|
      if (k == K_TAB)
 | 
						|
      {
 | 
						|
        f.set(s.row(pos).get(0));
 | 
						|
        s.post_select(pos);
 | 
						|
      }
 | 
						|
      else
 | 
						|
        s.select(pos);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
KEY TAlternative_browse::run()
 | 
						|
{
 | 
						|
  const TBrowse& b = *field().browse();
 | 
						|
  TCursor& c = cursor();
 | 
						|
 | 
						|
  TString caption = c.file().description();
 | 
						|
  if (caption.blank()) 
 | 
						|
    caption = TR("Selezione");
 | 
						|
 | 
						|
  TToken_string fields, head;
 | 
						|
  b.get_display_fields(head, fields);
 | 
						|
  const int pos = fields.get_pos(_altfld);
 | 
						|
  const int sz = c.curr().length(_altfld);
 | 
						|
 | 
						|
  if (pos > 0)
 | 
						|
  {
 | 
						|
    fields.destroy(pos); 
 | 
						|
    fields.insert_at(_altfld, 0);
 | 
						|
    TString80 h; head.get(pos, h);
 | 
						|
    head.destroy(pos); 
 | 
						|
    head.insert_at(h, 0); 
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    fields.insert_at(_altfld, 0);
 | 
						|
    TString80 h; h << "Cod.Alt.@" << sz;
 | 
						|
    head.insert_at(h, 0);
 | 
						|
  }
 | 
						|
 | 
						|
  TCursor_sheet sheet(&c, fields, caption, head, 0, 2);
 | 
						|
  TEdit_field& e = sheet.add_string(field().dlg(), 0, head.before('@'), 1, 1, sz, "U");
 | 
						|
  e.set_handler(alternative_code_handler);
 | 
						|
 | 
						|
  _curr_fbrowse = this;
 | 
						|
 | 
						|
  TString80 val = field().get();
 | 
						|
  val.strip("%");
 | 
						|
  e.set(val);
 | 
						|
  e.on_key(K_SPACE);
 | 
						|
  sheet.first_focus(e.dlg());
 | 
						|
  const KEY k = sheet.run();
 | 
						|
 | 
						|
  _curr_fbrowse = NULL;
 | 
						|
  
 | 
						|
  if (k == K_ENTER)
 | 
						|
  {
 | 
						|
    c = sheet.selected();
 | 
						|
    field().set(c.curr().get(_outfld));
 | 
						|
  }
 | 
						|
  return k;
 | 
						|
}
 | 
						|
 | 
						|
TAlternative_browse::TAlternative_browse(TEdit_field* ef, int altkey) : TFuzzy_browse(ef, altkey), _cursor(NULL)
 | 
						|
{ }
 | 
						|
 | 
						|
TAlternative_browse::~TAlternative_browse()
 | 
						|
{
 | 
						|
  if (_cursor) 
 | 
						|
    delete _cursor;
 | 
						|
}
 |