Correzioni su alberi

git-svn-id: svn://10.65.10.50/branches/R_10_00@22884 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2013-07-26 15:45:05 +00:00
parent f6f643fa96
commit 577159c75e
14 changed files with 321 additions and 93 deletions

View File

@ -888,15 +888,9 @@ void TAVM::execute(const TAVM_op& op)
break; break;
case avm_mul: case avm_mul:
{ {
const TVariant& v0 = _stack.pop();
const TVariant& v1 = _stack.pop(); const TVariant& v1 = _stack.pop();
TVariant& v0 = (TVariant&)_stack.peek(); _stack.push(v0.as_real() * v1.as_real());
if (v0.is_real())
{
const real m = v0.as_real() * v1.as_real();
v0.set(m);
}
else
log_error("Stack underflow");
} }
break; break;
case avm_negate: case avm_negate:

View File

@ -456,9 +456,9 @@ void TBrowse::parse_insert(TScanner& scanner)
int TBrowse::input_fields() int TBrowse::input_fields()
{ {
int inp = 0; int inp = 0;
for (const char* fld = _inp_id.get(0); fld; fld = _inp_id.get()) FOR_EACH_TOKEN(_inp_id, fld)
{ {
if (*fld != '"' && strchr(fld, '@') == NULL) if (*fld && *fld != '"' && strchr(fld, '@') == NULL)
{ {
TMask_field& f = field(field().atodlg(fld)); TMask_field& f = field(field().atodlg(fld));
if (f.active() && f.is_editable()) if (f.active() && f.is_editable())

View File

@ -46,7 +46,7 @@ extern "C" {
// @msg CHECKS | Macro che richiama una <m fatal_box> per stampare messaggi a video // @msg CHECKS | Macro che richiama una <m fatal_box> per stampare messaggi a video
#define CHECKS(p, m, s0) ( (p) ? (void)0 : (void) fatal_box( \ #define CHECKS(p, m, s0) ( (p) ? (void)0 : (void) fatal_box( \
"Check failed in %s, line %d:\n\r%s%s", \ "Check failed in %s, line %d:\n\r%s: %s", \
__FILE__, __LINE__, m, s0) ) __FILE__, __LINE__, m, s0) )
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE) // @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
// @parm | m | Messaggio da stampare // @parm | m | Messaggio da stampare
@ -62,7 +62,7 @@ extern "C" {
// @msg CHECKD | Macro che richiama una <m fatal_box> per stampare messaggi a video // @msg CHECKD | Macro che richiama una <m fatal_box> per stampare messaggi a video
#define CHECKD(p, m, d0) ( (p) ? (void)0 : (void) fatal_box( \ #define CHECKD(p, m, d0) ( (p) ? (void)0 : (void) fatal_box( \
"Check failed in %s, line %d:\n%s%d", \ "Check failed in %s, line %d:\n%s: %d", \
__FILE__, __LINE__, m, d0) ) __FILE__, __LINE__, m, d0) )
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE) // @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
// @parm | m | Messaggio da stampare // @parm | m | Messaggio da stampare

View File

@ -983,7 +983,16 @@ XI_RCT TControl::coord2rct(XI_OBJ* itf, short x, short y, short dx, short dy) co
rct.left = x * CHARX + X_DELTA; rct.left = x * CHARX + X_DELTA;
if (dx > 0 && MAXX > 80 * CHARX) if (dx > 0 && MAXX > 80 * CHARX)
rct.left += (MAXX - 80 * CHARX) / 2; {
if (itf->app_data2 & 0x1) // Full screen
{
// Don't offset fields
}
else
{
rct.left += (MAXX - 80 * CHARX) / 2; // Normal flow
}
}
} }
if (y < 0) if (y < 0)
@ -1287,7 +1296,7 @@ TText_control::TText_control(WINDOW win, short cid,
{ {
rct.right += (rct.right - rct.left); rct.right += (rct.right - rct.left);
rct.bottom += short(xvt_font_get_size(BIG_FONT) - xvt_font_get_size(DEF_FONT)); rct.bottom += short(xvt_font_get_size(BIG_FONT) - xvt_font_get_size(DEF_FONT));
} }
const unsigned long attrib = flags2attr(flags); const unsigned long attrib = flags2attr(flags);
XI_OBJ_DEF* def = xi_add_text_def(NULL, cid, &rct, attrib, t.get_buffer()); XI_OBJ_DEF* def = xi_add_text_def(NULL, cid, &rct, attrib, t.get_buffer());

View File

@ -220,6 +220,8 @@ real& TEval_stack::pop_real()
real& TEval_stack::peek_real() real& TEval_stack::peek_real()
{ {
if (count() == 0)
push(ZERO);
TValue& o = (TValue&)peek(0); TValue& o = (TValue&)peek(0);
return o.number(); return o.number();
} }
@ -232,6 +234,8 @@ TString& TEval_stack::pop_string()
TString& TEval_stack::peek_string() TString& TEval_stack::peek_string()
{ {
if (count() == 0)
push(EMPTY_STRING);
TValue& o = (TValue&)peek(0); TValue& o = (TValue&)peek(0);
return o.string(); return o.string();
} }

View File

@ -19,7 +19,33 @@
HIDDEN const char* const MASK_EXT = "msk"; HIDDEN const char* const MASK_EXT = "msk";
HIDDEN BOOLEAN _bShowGrid = FALSE; HIDDEN BOOLEAN _bShowGrid = FALSE;
//////////////////////////////////////////////////////////
// TMask scanner
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
struct TScanner_win : public TObject
{
WINDOW _win;
RCT _rct;
TScanner_win(WINDOW w) : _win(w) { xvt_vobj_get_client_rect(w, &_rct); }
};
void TMask_scanner::push_win(WINDOW w)
{ _pages.push(new TScanner_win(w)); }
WINDOW TMask_scanner::peek_win() const
{ return ((const TScanner_win&)_pages.peek())._win; }
RCT TMask_scanner::peek_rct() const
{ return ((const TScanner_win&)_pages.peek())._rct; }
WINDOW TMask_scanner::pop_win()
{ return ((const TScanner_win&)_pages.pop())._win; }
TMask_scanner::TMask_scanner(const TFilename& n) : TScanner(n)
{}
//////////////////////////////////////////////////////////
// TMask methods // TMask methods
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -141,7 +167,7 @@ void TMask::read_mask(
_source_file.ext(MASK_EXT); _source_file.ext(MASK_EXT);
_source_file.lower(); _source_file.lower();
_source_file.custom_path(); _source_file.custom_path();
TScanner scanner(_source_file); TMask_scanner scanner(_source_file);
if (num != 0) if (num != 0)
_mask_num = num; _mask_num = num;
@ -1168,7 +1194,7 @@ int TMask::sheets() const
// //
// @rdesc Ritorna l'handle della finestra creata // @rdesc Ritorna l'handle della finestra creata
void TMask::read_page( void TMask::read_page(
TScanner& scanner, // @parm File dal quale leggere la pagina TMask_scanner& scanner, // @parm File dal quale leggere la pagina
bool is_toolbar) // @parm Indica se e' la toolbar bool is_toolbar) // @parm Indica se e' la toolbar
// @comm Il parametro <p toolbar> e' utilizzato per indicare se la pagina deve essere visualizzata // @comm Il parametro <p toolbar> e' utilizzato per indicare se la pagina deve essere visualizzata
@ -1203,17 +1229,16 @@ void TMask::read_page(
if (l.starts_with("PA") || l.starts_with("TO")) // Ho trovato un'altra pagina! if (l.starts_with("PA") || l.starts_with("TO")) // Ho trovato un'altra pagina!
{ {
if (is_toolbar) if (is_toolbar)
{
create_book(false); // Crea notebook create_book(false); // Crea notebook
scanner.push_win(win()); // finestra principale
}
else else
{ {
//WINDOW w = create_interface(NULL_WIN, r.left, r.top, r.right, r.bottom, title, this);
//insert_page(w, 0); // Crea pagina principale
const WIN_TYPE wt = (r.right == 0) ? W_PLAIN : W_DOC; const WIN_TYPE wt = (r.right == 0) ? W_PLAIN : W_DOC;
const long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR; const long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR;
create(r.left, r.top, r.right, r.bottom, title, wsf, wt); create(r.left, r.top, r.right, r.bottom, title, wsf, wt);
const bool single = l.starts_with("TO"); // Crea sotto-pagina singola o multipla? const bool single = l.starts_with("TO"); // Crea sotto-pagina singola o multipla?
create_book(single); create_book(single);
} }
@ -1250,6 +1275,9 @@ void TMask::read_page(
} }
} }
} }
scanner.push_win(w);
while (scanner.popkey() != "EN") while (scanner.popkey() != "EN")
{ {
TMask_field* f = NULL; TMask_field* f = NULL;
@ -1278,6 +1306,8 @@ void TMask::read_page(
if (is_toolbar && r.top ==0 && _toolbar != NULL_WIN) if (is_toolbar && r.top ==0 && _toolbar != NULL_WIN)
xvt_toolbar_realize(_toolbar); xvt_toolbar_realize(_toolbar);
scanner.pop_win();
} }
bool TMask::check_current_field() const bool TMask::check_current_field() const
@ -1297,8 +1327,6 @@ WINDOW TMask::create_book(bool single)
WINDOW parent = win(); WINDOW parent = win();
if (parent == NULL_WIN) if (parent == NULL_WIN)
{ {
//parent = create_interface(NULL_WIN, 0, 0, 0, 0, "", this);
//set_win(parent);
parent = create(0, 0, 0, 0, "", WSF_INVISIBLE|WSF_NO_MENUBAR, W_PLAIN); parent = create(0, 0, 0, 0, "", WSF_INVISIBLE|WSF_NO_MENUBAR, W_PLAIN);
} }
if (single) if (single)

View File

@ -5,6 +5,10 @@
#include <maskfld.h> #include <maskfld.h>
#endif #endif
#ifndef __STACK_H
#include <stack.h>
#endif
// Numero massimo di righe logiche per maschere // Numero massimo di righe logiche per maschere
#define MAX_MASK_ROWS 23 #define MAX_MASK_ROWS 23
@ -29,6 +33,23 @@ enum TMaskmode {
MODE_MOD // @emem Modalita' di modifca dati MODE_MOD // @emem Modalita' di modifca dati
}; };
//////////////////////////////////////////////////////////
// TMask scanner
///////////////////////////////////////////////////////////
class TMask_scanner : public TScanner
{
TStack _pages;
public:
void push_win(WINDOW w);
WINDOW peek_win() const;
RCT peek_rct() const;
WINDOW pop_win();
TMask_scanner(const TFilename& n);
};
// @doc EXTERNAL // @doc EXTERNAL
// @class TMask | Classe per la gestione delle maschere video // @class TMask | Classe per la gestione delle maschere video
@ -122,7 +143,7 @@ protected:
// @cmember Inizializza la maschera // @cmember Inizializza la maschera
void init_mask(); void init_mask();
// @cmember Legge la pagina da file // @cmember Legge la pagina da file
void read_page(TScanner& scanner, bool toolbar); void read_page(TMask_scanner& scanner, bool toolbar);
// @cmember Aggiunge alla maschera tutti i bottoni per la navigazione tra le pagine // @cmember Aggiunge alla maschera tutti i bottoni per la navigazione tra le pagine
void set_tab_buttons(TToken_string& tabs); void set_tab_buttons(TToken_string& tabs);

View File

@ -646,7 +646,7 @@ const TString& TMask_field::get_default() const
return EMPTY_STRING; return EMPTY_STRING;
} }
const TString & TMask_field::evaluate_field(short id) const const TString& TMask_field::evaluate_field(short id) const
{ {
if (id == 0) if (id == 0)
return get(); return get();
@ -2029,11 +2029,12 @@ word TEdit_field::class_id() const
void TEdit_field::set_len(short w) void TEdit_field::set_len(short w)
{ {
CHECKD(w > 0 && w <= 50, "Invalid field length ", w);
_size = w;
} }
void TEdit_field::set_width(short width, short dwidth) void TEdit_field::set_width(short width, short dwidth)
{ {
RCT rect; RCT rect;
get_rect(rect); get_rect(rect);
rect.right= rect.left+width; rect.right= rect.left+width;
@ -2061,13 +2062,29 @@ void TEdit_field::parse_head(TScanner& scanner)
const TBrowse* TEdit_field::parse_browse(TScanner& scanner) const const TBrowse* TEdit_field::parse_browse(TScanner& scanner) const
{ {
const TBrowse* b = NULL; const TBrowse* b = NULL;
const int pos = mask().id2pos(scanner.integer());
short id = scanner.integer();
if (id != 0)
{
const TMask* m = &mask();
if (id < 0)
{
TSheet_field* sh = m->get_sheet();
if (sh != NULL)
{
m = &sh->mask();
id = -id;
}
}
const int pos = m->id2pos(id);
if (pos >= 0) if (pos >= 0)
{ {
const TMask_field& f = mask().fld(pos); const TMask_field& f = m->fld(pos);
if (f.is_edit()) if (f.is_edit())
b = ((TEdit_field&)f).browse(); b = ((TEdit_field&)f).browse();
} }
}
return b; return b;
} }
@ -2224,7 +2241,7 @@ bool TEdit_field::parse_item(TScanner& scanner)
if (scanner.key() == "CO") // Copyuse if (scanner.key() == "CO") // Copyuse
{ {
const TString8 what(scanner.popkey()); const TString8 what = scanner.popkey();
const TBrowse* b = parse_browse(scanner); const TBrowse* b = parse_browse(scanner);
if (b) if (b)
{ {

View File

@ -150,7 +150,9 @@ class TSpreadsheet : public TControl
TBit_array _column_disabled; TBit_array _column_disabled;
// @cmember:(INTERNAL) Array delle proprieta' delle righe // @cmember:(INTERNAL) Array delle proprieta' delle righe
TArray _property; TArray _properties;
// @cmember:(INTERNAL) Array delle proprieta' standard di tutte le righe
TRow_property* _row_properties;
// @cmember:(INTERNAL) Maschera in cui e' contenuto lo spreadsheet // @cmember:(INTERNAL) Maschera in cui e' contenuto lo spreadsheet
TMask _mask; TMask _mask;
@ -209,7 +211,7 @@ protected:
virtual void set_read_only(bool ro) { activate(!ro); } virtual void set_read_only(bool ro) { activate(!ro); }
virtual bool read_only() const { return !_active; } virtual bool read_only() const { return !_active; }
virtual void set_rect(const RCT& r) { xi_set_rect(_obj, (XI_RCT*)&r, true); }
KEY barcode_newline() const; KEY barcode_newline() const;
//@cmember Copia una cella nel corrispondente campo della maschera e ne ritorna il contenuto //@cmember Copia una cella nel corrispondente campo della maschera e ne ritorna il contenuto
@ -434,8 +436,8 @@ TSpreadsheet::TSpreadsheet(
_edit_field(NULL), _cur_row(0), _cur_rec(0), _cur_col(1), _edit_field(NULL), _cur_row(0), _cur_rec(0), _cur_col(1),
_row_dirty(false), _cell_dirty(false), _check_enabled(true), _row_dirty(false), _cell_dirty(false), _check_enabled(true),
_needs_update(-1), _selection_posted(-1), _ignore_button(0), _save_columns_order(false), _needs_update(-1), _selection_posted(-1), _ignore_button(0), _save_columns_order(false),
_f9_target(NULL), _auto_append(false), _first_nav_column_id(-1), _f9_target(NULL), _auto_append(false), _first_nav_column_id(-1),_last_nav_column_id(-1),
_last_nav_column_id(-1) _row_properties(NULL)
{ {
int m_width[MAX_COL], v_width[MAX_COL]; int m_width[MAX_COL], v_width[MAX_COL];
int fixed_cols = 0; // Number of fixed columns int fixed_cols = 0; // Number of fixed columns
@ -637,7 +639,9 @@ TSpreadsheet::TSpreadsheet(
} }
TSpreadsheet::~TSpreadsheet() TSpreadsheet::~TSpreadsheet()
{ } {
delete _row_properties;
}
TMask& TSpreadsheet::sheet_mask() const TMask& TSpreadsheet::sheet_mask() const
{ return ((TSpreadsheet*)this)->_mask; } { return ((TSpreadsheet*)this)->_mask; }
@ -882,7 +886,7 @@ int TSpreadsheet::insert(
TToken_string* toktok = new TToken_string(80, owner().separator()); TToken_string* toktok = new TToken_string(80, owner().separator());
r = _str.insert(toktok, rec); r = _str.insert(toktok, rec);
_property.insert(NULL, r, true); // Crea lo spazio necessario per le proprieta' _properties.insert(NULL, r, true); // Crea lo spazio necessario per le proprieta'
// Notifica che l'inserimento e' terminato // Notifica che l'inserimento e' terminato
owner().post_insert(r); owner().post_insert(r);
@ -931,12 +935,12 @@ bool TSpreadsheet::destroy(
if (rec < 0) if (rec < 0)
{ {
_str.destroy(); _str.destroy();
_property.destroy(); _properties.destroy();
set_dirty(_row_dirty = false); set_dirty(_row_dirty = false);
} }
else else
{ {
_property.destroy(rec, true); // Destroy line info _properties.destroy(rec, true); // Destroy line info
ok = _str.destroy(rec, true); // Destroy line ok = _str.destroy(rec, true); // Destroy line
} }
@ -2130,11 +2134,18 @@ void TSpreadsheet::set_back_and_fore_color(COLOR back, COLOR fore, int row, int
if (prop) if (prop)
prop->set(col, back, fore); prop->set(col, back, fore);
} }
if (row < 0)
{
TRow_property* prop = get_property(row, true);
prop->set(col, back, fore);
}
} }
bool TSpreadsheet::get_back_and_fore_color(COLOR& back, COLOR& fore, int row, int col) bool TSpreadsheet::get_back_and_fore_color(COLOR& back, COLOR& fore, int row, int col)
{ {
TRow_property* prop = get_property(row, false); TRow_property* prop = get_property(row, false);
if (prop == NULL)
prop = get_property(-1, false);
if (prop != NULL) if (prop != NULL)
return prop->get(col, back, fore); return prop->get(col, back, fore);
return false; return false;
@ -2234,7 +2245,7 @@ void TSpreadsheet::swap_rows( const int fromindex, const int toindex)
if (fromindex != toindex) if (fromindex != toindex)
{ {
_str.swap(fromindex, toindex); _str.swap(fromindex, toindex);
_property.swap(fromindex, toindex); _properties.swap(fromindex, toindex);
} }
} }
@ -2246,9 +2257,9 @@ void TSpreadsheet::move_row(const int fromindex, const int toindex)
_str.insert(r, toindex, true); _str.insert(r, toindex, true);
_str.pack(); _str.pack();
TObject* p = _property.remove(fromindex); TObject* p = _properties.remove(fromindex);
_property.insert(p, toindex, true); _properties.insert(p, toindex, true);
_property.pack(); _properties.pack();
} }
} }
@ -2325,11 +2336,21 @@ void TSpreadsheet::set_row_height(const int row, const int height)
TRow_property* TSpreadsheet::get_property(int row, bool create) TRow_property* TSpreadsheet::get_property(int row, bool create)
{ {
TRow_property* p = (TRow_property*)_property.objptr(row); if (row < 0)
if (p == NULL && create) {
if (_row_properties == NULL && create)
_row_properties = new TRow_property;
return _row_properties;
}
TRow_property* p = (TRow_property*)_properties.objptr(row);
if (p == NULL)
{
if (create)
{ {
p = new TRow_property; p = new TRow_property;
_property.add(p, row); _properties.add(p, row);
}
} }
return p; return p;
} }
@ -3507,14 +3528,15 @@ TRectype* TSheet_field::putkey(const TRelation& r)
// Certified: ...under debug.. // Certified: ...under debug..
bool TSheet_field::autoload_line(int i, const TRectype& rec) bool TSheet_field::autoload_line(int i, const TRectype& rec)
{ {
TMask& m = sheet_row_mask(i-1);
TToken_string &row= this->row(i-1); TToken_string &row= this->row(i-1);
row.cut(0); row.cut(0);
for (short id = FIRST_FIELD; id <= _last_column_id; id++) for (short id = FIRST_FIELD; id <= _last_column_id; id++)
{ {
TMask_field& mf = sheet_mask().field(id); const TFieldref* dbfield = m.field(id).field();
const TFieldref* dbfield = mf.field(); if (dbfield == NULL && m.id2pos(id+100) > 0) // Succede coi campi analitici
dbfield = m.field(id+100).field();
if (dbfield) if (dbfield)
row.add(dbfield->read(rec),id - FIRST_FIELD); row.add(dbfield->read(rec),id - FIRST_FIELD);
} }
@ -3528,11 +3550,12 @@ bool TSheet_field::autoload_line(int i, const TRectype& rec)
// Certified: ...under debug.. // Certified: ...under debug..
bool TSheet_field::autosave_line(int i,TRectype & rec) bool TSheet_field::autosave_line(int i,TRectype & rec)
{ {
TMask& m = sheet_row_mask(i-1);
for (short id = FIRST_FIELD; id <= _last_column_id; id++) for (short id = FIRST_FIELD; id <= _last_column_id; id++)
{ {
TMask_field& mf = sheet_mask().field(id); const TFieldref* dbfield = m.field(id).field();
const TFieldref* dbfield = mf.field(); if (dbfield == NULL && m.id2pos(id+100) > 0) // Succede coi campi analitici
dbfield = m.field(id+100).field();
if (dbfield) if (dbfield)
dbfield->write(cell(i - 1, id - FIRST_FIELD), rec); dbfield->write(cell(i - 1, id - FIRST_FIELD), rec);
} }
@ -3552,7 +3575,7 @@ bool TSheet_field::autoload(const TRelation& rel)
// trasferisce le linee dal record array allo sheet // trasferisce le linee dal record array allo sheet
destroy(); // cancella lo sheet destroy(); // cancella lo sheet
const int last_line = _linee_rec->last_row(); const int last_line = _linee_rec->last_row();
for (int i= 1; i <= last_line; i++) for (int i = 1; i <= last_line; i++)
autoload_line(i,_linee_rec->row(i, true)); autoload_line(i,_linee_rec->row(i, true));
return(0); return(0);

View File

@ -28,7 +28,7 @@ void TPrintwin::paint_background(long j)
TPrinter& pr = printer(); TPrinter& pr = printer();
const bool isbackground = _bg->items() > 0 && pr.isgraphics(); const bool isbackground = _bg->items() > 0 && pr.isgraphics();
const bool fink_mode = pr.get_fink_mode(); const bool fink_mode = pr.get_fink_mode();
int rw = (int)(j % _formlen); const int rw = (int)(j % _formlen);
int cnt = 0; char ch; int cnt = 0; char ch;
char curcol = 'n'; char curcol = 'n';
@ -46,9 +46,11 @@ void TPrintwin::paint_background(long j)
xvt_dwin_draw_text(win(), _hofs , (rw*_chary + _chary - _descent + _vofs), (char*)line, -1); xvt_dwin_draw_text(win(), _hofs , (rw*_chary + _chary - _descent + _vofs), (char*)line, -1);
// return; // return;
} }
if (!isbackground) return; if (!isbackground)
return;
TString& rwd = (TString&)(*_bg)[rw]; const TString* rbg = (const TString*)_bg->objptr(rw);
const TString& rwd = rbg ? *rbg : EMPTY_STRING;
while ((ch = rwd[cnt++])) while ((ch = rwd[cnt++]))
{ {

View File

@ -419,7 +419,7 @@ bool TRelation_application::autonum(
if (rec) if (rec)
((TEditable_field&)f).autosave(*get_relation()); ((TEditable_field&)f).autosave(*get_relation());
if (_renum_message.empty() || f.in_key(1)) if (_renum_message.empty() || f.in_key(1))
_renum_message.format("L'elemento e' stato registrato con :\n %s = %s", (const char *) f.prompt(), (const char *) f.get()); _renum_message.format("L'elemento è stato registrato con :\n %s = %s", (const char*)f.prompt(), (const char*)f.get());
} }
return k.not_empty(); return k.not_empty();
} }
@ -916,11 +916,11 @@ bool TRelation_application::test_key(
word k, // @parm Chiave da ricercare word k, // @parm Chiave da ricercare
bool err) // @parm Indica se visualizzare eventuali errori occorsi bool err) // @parm Indica se visualizzare eventuali errori occorsi
{ {
bool onereq = FALSE, onefill = FALSE; bool onereq = false, onefill = false;
for (TEditable_field* e = _mask->get_key_field(k, TRUE); for (TEditable_field* e = _mask->get_key_field(k, true);
e != NULL; e != NULL;
e = _mask->get_key_field(k, FALSE)) e = _mask->get_key_field(k, false))
{ {
if (e->required() && e->shown()) if (e->required() && e->shown())
{ {
@ -956,7 +956,7 @@ bool TRelation_application::test_key(
{ {
if (err) if (err)
error_box(TR("Manca un valore indispensabile per la ricerca")); error_box(TR("Manca un valore indispensabile per la ricerca"));
return FALSE; return false;
} }
return onefill || onereq; return onefill || onereq;
} }
@ -970,15 +970,17 @@ bool TRelation_application::find(word k)
return test_key(1, TRUE); return test_key(1, TRUE);
} }
file().setkey(k); TRelation& rel = *get_relation();
file().zero(); TLocalisamfile& fil = rel.file();
for (TEditable_field* e = _mask->get_key_field(k, TRUE); e; e = _mask->get_key_field(k, FALSE)) fil.setkey(k);
fil.zero();
for (TEditable_field* e = _mask->get_key_field(k, true); e; e = _mask->get_key_field(k, false))
{ {
if (e->shown()) // Ignora campi invisibili if (e->shown()) // Ignora campi invisibili
e->autosave(*get_relation()); e->autosave(rel);
} }
const int err = file().read(_isequal); const int err = fil.read(_isequal);
return err == NOERR; return err == NOERR;
} }

View File

@ -7,7 +7,7 @@
// Callbacks // Callbacks
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
HIDDEN bool callback_compare_node(TTree& node, void* jolly, word when) HIDDEN bool callback_compare_node(TTree& node, void* jolly, word /*when*/)
{ {
const TString& id = *((TString*)jolly); const TString& id = *((TString*)jolly);
TString cur_id; node.curr_id(cur_id); TString cur_id; node.curr_id(cur_id);
@ -157,6 +157,18 @@ bool TTree::scan_breadth_first(NODE_HANDLER nh, void* jolly, word flags)
return false; return false;
} }
int TTree::curr_depth() const
{
int n = -1;
if (has_root())
{
TString myself; curr_id(myself);
for (n = 0; ((TTree*)this)->goto_father(); n++);
((TTree*)this)->goto_node(myself);
}
return n;
}
bool TTree::has_root() const bool TTree::has_root() const
{ {
TString myself; curr_id(myself); TString myself; curr_id(myself);
@ -459,24 +471,18 @@ void TObject_tree::node2id(const TObject* node, TString& id) const
bool TObject_tree::goto_node(const TString& node) bool TObject_tree::goto_node(const TString& node)
{ {
void* p = NULL; bool ok = goto_root();
if (node.not_empty()) if (node.full())
{ {
#ifdef DBG_TREE #ifdef DBG_TREE
if (!_expanded.is_key(node)) // Usa l'assoc array per testare i nodi validi! if (!_expanded.is_key(node)) // Usa l'assoc array per testare i nodi validi!
{ {
NFCHECK("Invalid node: %s", (const char*)node); NFCHECK("Invalid node: %s", (const char*)node);
return goto_root(); return false;
} }
#endif #endif
sscanf(node, "%p", &p); ok = scan_depth_first(callback_compare_node, (void*)&node);
} }
bool ok = true;
if (p == NULL)
ok = goto_root();
else
_current = (TTree_node*)p;
return ok; return ok;
} }
@ -516,14 +522,13 @@ bool TObject_tree::goto_lbrother()
bool TObject_tree::set_object(TObject* obj) bool TObject_tree::set_object(TObject* obj)
{ {
if (_current) if (_current && _current->_obj != obj)
{ {
#ifdef DBG_TREE #ifdef DBG_TREE
TString str; curr_id(str); TString str; curr_id(str);
_expanded.add(str); // Usa l'assoc array per memorizzare i nodi validi! _expanded.add(str); // Usa l'assoc array per memorizzare i nodi validi!
#endif #endif
if (_current->_obj) delete detach_object();
delete _current->_obj;
_current->_obj = obj; _current->_obj = obj;
} }
return _current != NULL; return _current != NULL;
@ -542,6 +547,92 @@ bool TObject_tree::set_object(const TObject& obj)
return ok; return ok;
} }
TObject* TObject_tree::detach_object()
{
TObject* o = NULL;
if (_current && _current->_obj)
{
o = _current->_obj;
_current->_obj = NULL;
}
return o;
}
#define swap_obj(o1, o2) { auto o0 = o1; o1 = o2; o2 = o0; }
void TObject_tree::reparent(TObject_tree::TTree_node* son, TObject_tree::TTree_node* father)
{
while (son)
{
son->_father = father;
son = son->_rbrother;
}
}
bool TObject_tree::swap_left()
{
const bool ok = goto_lbrother();
if (ok)
{
reparent(_current->_rbrother->_son, _current);
reparent(_current->_son, _current->_rbrother);
swap_obj(_current->_son, _current->_rbrother->_son);
swap_obj(_current->_obj, _current->_rbrother->_obj);
}
return ok;
}
bool TObject_tree::swap_right()
{
const bool ok = goto_rbrother();
if (ok)
{
reparent(_current->_lbrother->_son, _current);
reparent(_current->_son, _current->_lbrother);
swap_obj(_current->_son, _current->_lbrother->_son);
swap_obj(_current->_obj, _current->_lbrother->_obj);
}
return ok;
}
bool TObject_tree::push_down()
{
bool ok = _current != NULL;
if (ok)
{
TObject* obj = detach_object();
set_object(obj->dup());
TTree_node* child = _current->_son;
_current->_son = NULL;
add_son(obj);
_current->_son = child;
reparent(child, _current);
}
return ok;
}
bool TObject_tree::push_up()
{
bool ok = has_father();
if (ok)
{
const bool is_single = !has_lbrother() && !has_rbrother();
TObject* obj = detach_object();
TTree_node* child = _current->_son;
_current->_son = NULL;
TTree_node* cur = _current->_father;
kill_node();
_current = cur;
if (is_single)
set_object(obj);
else
add_rbrother(obj);
_current->_son = child;
reparent(child, _current);
}
return ok;
}
bool TObject_tree::create_root() bool TObject_tree::create_root()
{ {
if (!has_root()) if (!has_root())
@ -604,10 +695,15 @@ bool TObject_tree::add_rbrother(TObject* obj)
bool ok = false; bool ok = false;
if (has_root()) // was has_father(); changed for sc0300 09/03/2012 if (has_root()) // was has_father(); changed for sc0300 09/03/2012
{ {
CHECK(_current, "Can't add_rbrother to NULL node");
TTree_node* newbrother = new TTree_node; TTree_node* newbrother = new TTree_node;
newbrother->_father = _current->_father; newbrother->_father = _current->_father;
newbrother->_lbrother = _current; newbrother->_lbrother = _current;
if (_current->_rbrother != NULL)
{
newbrother->_rbrother = _current->_rbrother; newbrother->_rbrother = _current->_rbrother;
_current->_rbrother->_lbrother = newbrother;
}
_current->_rbrother = newbrother; _current->_rbrother = newbrother;
ok = goto_rbrother(); ok = goto_rbrother();
} }
@ -630,19 +726,20 @@ bool TObject_tree::add_rbrother(const TObject& obj)
bool TObject_tree::add_lbrother(TObject* obj) bool TObject_tree::add_lbrother(TObject* obj)
{ {
bool ok = false; bool ok = true;
if (has_root()) // was has_father(); changed for sc0300 09/03/2012 if (has_root()) // was has_father(); changed for sc0300 09/03/2012
{ {
if (_current->_lbrother == NULL) if (goto_lbrother())
ok = add_brother(obj); ok = add_rbrother(obj);
else else
{ {
TTree_node* newbrother = new TTree_node; TTree_node* newbrother = new TTree_node;
newbrother->_father = _current->_father; newbrother->_father = _current->_father;
newbrother->_rbrother = _current; newbrother->_rbrother = _current;
newbrother->_lbrother = _current->_lbrother;
_current->_lbrother = newbrother; _current->_lbrother = newbrother;
ok = goto_lbrother(); if (_current->_father != NULL)
_current->_father->_son = newbrother;
_current = newbrother;
} }
} }
else else
@ -718,6 +815,18 @@ bool TObject_tree::get_description(TString& str) const
return obj != NULL; return obj != NULL;
} }
int TObject_tree::curr_depth() const
{
int n = -1;
if (_current != NULL)
{
const TTree_node* curr = _current;
for (n = 0; curr->_father; n++)
curr = curr->_father;
}
return n;
}
TObject_tree::TObject_tree() TObject_tree::TObject_tree()
{ {
_root = _current = NULL; _root = _current = NULL;

View File

@ -40,7 +40,7 @@ public:
virtual bool goto_rbrother() pure; virtual bool goto_rbrother() pure;
virtual bool goto_node(const TString &id) pure; virtual bool goto_node(const TString &id) pure;
virtual TObject* curr_node() const pure; virtual TObject* curr_node() const pure;
virtual int curr_depth() const;
virtual bool has_root() const; virtual bool has_root() const;
virtual bool has_father() const; virtual bool has_father() const;
virtual bool could_have_son() const; // Is not terminal node virtual bool could_have_son() const; // Is not terminal node
@ -112,6 +112,7 @@ class TObject_tree : public TBidirectional_tree
TTree_node *_root, *_current; TTree_node *_root, *_current;
bool create_root(); // Internal use only bool create_root(); // Internal use only
void reparent(TObject_tree::TTree_node* son1, TObject_tree::TTree_node* father);
protected: protected:
virtual void node2id(const TObject* node, TString& id) const; virtual void node2id(const TObject* node, TString& id) const;
@ -141,6 +142,7 @@ public: // TTree
virtual bool expanded() const; virtual bool expanded() const;
public: // TBidirectional_tree public: // TBidirectional_tree
virtual int curr_depth() const;
virtual bool has_father() const { return _current && _current->_father; } virtual bool has_father() const { return _current && _current->_father; }
virtual bool has_lbrother() const { return _current && _current->_lbrother; } virtual bool has_lbrother() const { return _current && _current->_lbrother; }
virtual bool goto_father(); virtual bool goto_father();
@ -151,6 +153,13 @@ public: // TBidirectional_tree
public: public:
bool set_object(TObject* obj); bool set_object(TObject* obj);
bool set_object(const TObject& obj); bool set_object(const TObject& obj);
TObject* detach_object();
bool swap_left();
bool swap_right();
bool push_down();
bool push_up();
virtual bool kill_node(); virtual bool kill_node();
TObject_tree(); TObject_tree();

View File

@ -354,9 +354,18 @@ void TTree_window::set_tree(TTree* tree)
if (_tree != NULL) if (_tree != NULL)
{ {
// Memorizza la posizione dell'albero per dopo ... // Memorizza la posizione dell'albero per dopo ...
TString curr; tree->curr_id(curr); TString curr; _tree->curr_id(curr);
if (xvt_vobj_is_focusable(win())) // Devo nascondere la finestra per evitare sfarfallii?
{
xvt_vobj_set_visible(_ctrl, false);
create_children(NULL); // Rigenera i figli della radice create_children(NULL); // Rigenera i figli della radice
if (tree->goto_node(curr)) // Riporta la selezione sul nodo memorizzato xvt_vobj_set_visible(_ctrl, true);
}
else
create_children(NULL); // Rigenera i figli della radice
// Riporta la selezione sul nodo memorizzato
if (_tree->goto_node(curr))
select_current(); select_current();
} }
} }
@ -621,6 +630,7 @@ void TTree_field::set_tree(TTree* tree)
TTree_window& tv = tree_win(); TTree_window& tv = tree_win();
tv.set_tree(tree); tv.set_tree(tree);
} }
void TTree_field::force_update() void TTree_field::force_update()
{ set_tree(tree()); } { set_tree(tree()); }