Patch level : 10.0

Files correlati     : tutti
Ricompilazione Demo : [ ]
Commento            :
Nuova ricerca intelligente con testo parziale e somigliante


git-svn-id: svn://10.65.10.50/branches/R_10_00@22605 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2012-03-09 15:47:51 +00:00
parent dfcef6b5b5
commit 4b3a4344c9
4 changed files with 262 additions and 112 deletions

View File

@ -1038,7 +1038,21 @@ TToken_string& TBrowse::create_siblings(TToken_string& siblings) const
KEY TBrowse::run()
{
if (_alt_browse && field().get().starts_with("%"))
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)
@ -1170,15 +1184,30 @@ bool TBrowse::check(CheckTime t)
CheckType chk = field().check_type();
// Se ho la ricerca alternativa ed il campo comincia per % ...
if (_alt_browse != NULL && t == RUNNING_CHECK && field().get()[0]=='%')
if (t == RUNNING_CHECK)
{
if (_alt_browse->check(t))
const TString& magic = field().get();
if (magic[0] == '*' && cursor()->key() > 1)
{
if (chk == CHECK_NONE) // Se trovo la chiave forzo gli output (RAGSOC in righe prima nota)
chk = CHECK_NORMAL;
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;
}
else
return false;
}
if (chk != CHECK_NONE)
@ -1574,6 +1603,173 @@ bool TReport_select::check(CheckTime ct)
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 (isalnum(*s)) *d++ = *s;
*d = '\0';
str.upper();
}
TRecnotype TFuzzy_browse::find(const TString& raw_val)
{
const TBrowse& b = *field().browse();
TCursor& c = cursor();
TString80 magic_val = raw_val;
clean_string(magic_val);
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;
const int testlen = magic_val.len()+1;
if (testlen > 3)
{
double best = 0.66;
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;
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();
field().set(c.curr().get(_outfld));
}
return k;
}
TFuzzy_browse::TFuzzy_browse(TEdit_field* ef, int altkey) : TBrowse_button(ef), _altkey(altkey)
{
}
///////////////////////////////////////////////////////////
// TAlternative_browse
///////////////////////////////////////////////////////////
@ -1623,55 +1819,6 @@ TCursor& TAlternative_browse::cursor()
return *_cursor;
}
bool TAlternative_browse::check(CheckTime /*t*/)
{
const TBrowse& b = *field().browse();
TCursor& c = cursor();
TString80 magic_val;
magic_val = field().get();
magic_val.strip("%");
magic_val.trim();
magic_val.upper();
c = 0L;
TRectype& curr = c.curr();
curr.put(_altfld, magic_val);
c.read();
if (curr.get(_altfld).starts_with(magic_val))
{
field().set(curr.get(_outfld));
return true;
}
curr.put(_altfld, magic_val.left(1));
double best = 0;
for (int err = c.read(); err == NOERR; ++c)
{
const TString& val = curr.get(_altfld);
if (val[0] != magic_val[0])
break;
double n = xvt_str_fuzzy_compare(magic_val, val);
if (n < best && n < 0.5 && val.find(magic_val) >= 0)
n += 0.3;
if (n > best && n > 0.6)
{
best = n;
field().set(curr.get(_outfld));
if (n == 1.0)
break;
}
}
return best > 0;
}
static TAlternative_browse* _curr_browse = NULL;
static bool alternative_code_handler(TMask_field& f, KEY k)
{
if (k == K_F2)
@ -1679,20 +1826,20 @@ static bool alternative_code_handler(TMask_field& f, KEY k)
f.reset();
k = K_SPACE;
}
if (k == K_SPACE)
if (k == K_SPACE || k == K_TAB)
{
TCursor& c = _curr_browse->cursor();
TRectype& curr = c.curr();
const RecDes& rd = curr.rec_des();
const KeyDes& kd = rd.Ky[c.key()-1];
const int mf = kd.FieldSeq[kd.NkFields-1] % MaxFields;
const char* altfld = rd.Fd[mf].Name;
curr.put(altfld, ((TEdit_field&)f).get_window_data());
const TRecnotype pos = c.read();
if (pos >= 0 && pos < c.items())
const TString& str = ((TEdit_field&)f).get_window_data();
const TRecnotype pos = _curr_fbrowse->find(str);
if (pos >= 0)
{
TSheet& s = (TSheet&)f.mask();
s.select(pos);
if (k == K_TAB)
{
f.set(s.row(pos).get(0));
s.post_select(pos);
}
else
s.select(pos);
}
}
@ -1732,26 +1879,16 @@ KEY TAlternative_browse::run()
TEdit_field& e = sheet.add_string(field().dlg(), 0, head.before('@'), 1, 1, sz, "U");
e.set_handler(alternative_code_handler);
if (c.items() > 0)
{
TString80 magic_val;
magic_val = field().get();
magic_val.strip("%");
magic_val.trim();
magic_val.upper();
if (magic_val.full())
{
e.set(magic_val);
c.curr().put(_altfld, magic_val);
c.read();
}
else
c = 0L;
}
_curr_fbrowse = this;
_curr_browse = 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_browse = NULL;
_curr_fbrowse = NULL;
if (k == K_ENTER)
{
@ -1761,9 +1898,8 @@ KEY TAlternative_browse::run()
return k;
}
TAlternative_browse::TAlternative_browse(TEdit_field* ef, int altkey) : TBrowse_button(ef), _altkey(altkey), _cursor(NULL)
{
}
TAlternative_browse::TAlternative_browse(TEdit_field* ef, int altkey) : TFuzzy_browse(ef, altkey), _cursor(NULL)
{ }
TAlternative_browse::~TAlternative_browse()
{

View File

@ -294,21 +294,35 @@ public:
virtual KEY run();
};
class TAlternative_browse : public TBrowse_button
class TFuzzy_browse : public TBrowse_button
{
int _altkey;
TString16 _altfld, _outfld;
TCursor* _cursor;
protected:
virtual void parse_input(TScanner& scanner) {}
virtual void parse_output(TScanner& scanner) {}
virtual bool check(CheckTime = RUNNING_CHECK);
protected:
const int _altkey;
TString16 _altfld, _outfld;
virtual TCursor& cursor();
public:
TCursor& cursor();
virtual bool check(CheckTime = RUNNING_CHECK);
virtual KEY run();
virtual long find(const TString& val);
TFuzzy_browse (TEdit_field* ef, int key);
};
class TAlternative_browse : public TFuzzy_browse
{
TCursor* _cursor;
protected:
virtual TCursor& cursor();
public:
virtual KEY run();
TAlternative_browse(TEdit_field* ef, int altkey);
~TAlternative_browse();
};

View File

@ -14,7 +14,7 @@ class TSheet : public TMask
// @author:(INTERNAL) Guido
// @access:(INTERNAL) Privete Member
// @access:(INTERNAL) Private Members
{
friend class TSheet_control;
TSheet_control* _sheet; // Spreadsheet contenuto
@ -23,7 +23,7 @@ class TSheet : public TMask
long _select_row; // Riga da selezionare
long _parked; // Numero riga parcheggiata
// @access Protected Member
// @access Protected Members
protected: // TMask
// @cmember Lavori in background
@ -44,8 +44,6 @@ protected:
virtual void repos_buttons() const;
virtual bool get_cell_colors(int row, int col, COLOR& fore, COLOR& back) const;
void post_select(long rec);
void save_columns_order(const TEdit_field& field);
void set_columns_order(TToken_string* col);
void load_columns_order(const TEdit_field& f);
@ -58,6 +56,8 @@ public: // TWindow
// @cmember Inizializzazione
virtual void start_run();
void post_select(long rec); // Select on idle
public:
// @cmember Aggiunge un bottone nella finestra
void add_button(short id, const char* caption, KEY key, short bmp_up = 0, short bmp_dn = 0);
@ -75,30 +75,30 @@ public:
// @cmember Ritorna se la riga <p n>-esima e' attivata
bool checked(long n) const;
// @cmember Permette di attivare/disattivare una riga
void check(long n, bool on = TRUE);
void check(long n, bool on = true);
// @cmember Permette di disattivare una riga (chiama <mf TSheet::check>)
void uncheck(long n)
{ check(n, FALSE); }
// @cmember Permette di abilitare (<p yn> = TRUE) o disabilitare (<p yn> = FALSE)
{ check(n, false); }
// @cmember Permette di abilitare (<p yn> = true) o disabilitare (<p yn> = false)
// la gestione dei check sullo sheet
void enable_check(bool on = TRUE);
// @cmember Permette di disabilitare (<p yn> = FALSE) i check sullo sheet
void enable_check(bool on = true);
// @cmember Permette di disabilitare (<p yn> = false) i check sullo sheet
void disable_check()
{ enable_check(FALSE); }
// @cmember Ritorna TRUE se e' possibile mettere un check sulle righe
{ enable_check(false); }
// @cmember Ritorna true se e' possibile mettere un check sulle righe
bool check_enabled() const;
// @cmember Abilita/disabilita una riga
void enable_row(long n, bool on = TRUE);
void enable_row(long n, bool on = true);
// @cmember Disabilita una riga (chiama <mf TSheet::enable_row>)
void disable_row(long n)
{ enable_row(n, FALSE); }
{ enable_row(n, false); }
// @cmember Ritorna se e' abilitata la riga <p n>-esima
bool row_enabled(long n) const;
// @cmember Ritorna se e' disabilitata la riga <p n>-esima
bool row_disabled(long n) const { return ! row_enabled(n); }
// @cmember Ritorna se esistono elementi attivati nello sheet (TRUE se esitono)
// @cmember Ritorna se esistono elementi attivati nello sheet (true se esitono)
bool one_checked() const;
// @cmember Ritorna il numero di elementi attivati (vedi <mf TBit_array::ones>)
long checked() const;

View File

@ -602,7 +602,7 @@ bool TObject_tree::add_brother(const TObject& obj)
bool TObject_tree::add_rbrother(TObject* obj)
{
bool ok = false;
if (has_father())
if (has_root()) // was has_father(); changed for sc0300 09/03/2012
{
TTree_node* newbrother = new TTree_node;
newbrother->_father = _current->_father;
@ -631,7 +631,7 @@ bool TObject_tree::add_rbrother(const TObject& obj)
bool TObject_tree::add_lbrother(TObject* obj)
{
bool ok = false;
if (has_father())
if (has_root()) // was has_father(); changed for sc0300 09/03/2012
{
if (_current->_lbrother == NULL)
ok = add_brother(obj);