diff --git a/include/brwbut.cpp b/include/brwbut.cpp index 048ba9637..00c1659c2 100644 --- a/include/brwbut.cpp +++ b/include/brwbut.cpp @@ -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() { diff --git a/include/brwbut.h b/include/brwbut.h index b37b3f9f3..bdaa03c51 100644 --- a/include/brwbut.h +++ b/include/brwbut.h @@ -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(); }; diff --git a/include/sheet.h b/include/sheet.h index 34b6b5498..18bc91d1e 100755 --- a/include/sheet.h +++ b/include/sheet.h @@ -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

-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 ) void uncheck(long n) - { check(n, FALSE); } - // @cmember Permette di abilitare (

= TRUE) o disabilitare (

= FALSE) + { check(n, false); } + // @cmember Permette di abilitare (

= true) o disabilitare (

= false) // la gestione dei check sullo sheet - void enable_check(bool on = TRUE); - // @cmember Permette di disabilitare (

= FALSE) i check sullo sheet + void enable_check(bool on = true); + // @cmember Permette di disabilitare (

= 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 ) void disable_row(long n) - { enable_row(n, FALSE); } + { enable_row(n, false); } // @cmember Ritorna se e' abilitata la riga

-esima bool row_enabled(long n) const; // @cmember Ritorna se e' disabilitata la riga

-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 ) long checked() const; diff --git a/include/tree.cpp b/include/tree.cpp index 0639d0483..b2c183865 100755 --- a/include/tree.cpp +++ b/include/tree.cpp @@ -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);