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:
parent
f6f643fa96
commit
577159c75e
@ -888,15 +888,9 @@ void TAVM::execute(const TAVM_op& op)
|
||||
break;
|
||||
case avm_mul:
|
||||
{
|
||||
const TVariant& v0 = _stack.pop();
|
||||
const TVariant& v1 = _stack.pop();
|
||||
TVariant& v0 = (TVariant&)_stack.peek();
|
||||
if (v0.is_real())
|
||||
{
|
||||
const real m = v0.as_real() * v1.as_real();
|
||||
v0.set(m);
|
||||
}
|
||||
else
|
||||
log_error("Stack underflow");
|
||||
_stack.push(v0.as_real() * v1.as_real());
|
||||
}
|
||||
break;
|
||||
case avm_negate:
|
||||
|
@ -456,9 +456,9 @@ void TBrowse::parse_insert(TScanner& scanner)
|
||||
int TBrowse::input_fields()
|
||||
{
|
||||
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));
|
||||
if (f.active() && f.is_editable())
|
||||
|
@ -46,7 +46,7 @@ extern "C" {
|
||||
|
||||
// @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( \
|
||||
"Check failed in %s, line %d:\n\r%s%s", \
|
||||
"Check failed in %s, line %d:\n\r%s: %s", \
|
||||
__FILE__, __LINE__, m, s0) )
|
||||
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
|
||||
// @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
|
||||
#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) )
|
||||
// @parm | p | Condizione per la stampa del messaggio (stampa se FALSE)
|
||||
// @parm | m | Messaggio da stampare
|
||||
|
@ -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;
|
||||
|
||||
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)
|
||||
@ -1287,7 +1296,7 @@ TText_control::TText_control(WINDOW win, short cid,
|
||||
{
|
||||
rct.right += (rct.right - rct.left);
|
||||
rct.bottom += short(xvt_font_get_size(BIG_FONT) - xvt_font_get_size(DEF_FONT));
|
||||
}
|
||||
}
|
||||
|
||||
const unsigned long attrib = flags2attr(flags);
|
||||
XI_OBJ_DEF* def = xi_add_text_def(NULL, cid, &rct, attrib, t.get_buffer());
|
||||
|
@ -220,6 +220,8 @@ real& TEval_stack::pop_real()
|
||||
|
||||
real& TEval_stack::peek_real()
|
||||
{
|
||||
if (count() == 0)
|
||||
push(ZERO);
|
||||
TValue& o = (TValue&)peek(0);
|
||||
return o.number();
|
||||
}
|
||||
@ -232,6 +234,8 @@ TString& TEval_stack::pop_string()
|
||||
|
||||
TString& TEval_stack::peek_string()
|
||||
{
|
||||
if (count() == 0)
|
||||
push(EMPTY_STRING);
|
||||
TValue& o = (TValue&)peek(0);
|
||||
return o.string();
|
||||
}
|
||||
|
@ -19,7 +19,33 @@
|
||||
HIDDEN const char* const MASK_EXT = "msk";
|
||||
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
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
@ -141,7 +167,7 @@ void TMask::read_mask(
|
||||
_source_file.ext(MASK_EXT);
|
||||
_source_file.lower();
|
||||
_source_file.custom_path();
|
||||
TScanner scanner(_source_file);
|
||||
TMask_scanner scanner(_source_file);
|
||||
|
||||
if (num != 0)
|
||||
_mask_num = num;
|
||||
@ -1168,7 +1194,7 @@ int TMask::sheets() const
|
||||
//
|
||||
// @rdesc Ritorna l'handle della finestra creata
|
||||
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
|
||||
|
||||
// @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 (is_toolbar)
|
||||
{
|
||||
create_book(false); // Crea notebook
|
||||
scanner.push_win(win()); // finestra principale
|
||||
}
|
||||
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 long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR;
|
||||
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?
|
||||
create_book(single);
|
||||
}
|
||||
@ -1250,6 +1275,9 @@ void TMask::read_page(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scanner.push_win(w);
|
||||
|
||||
while (scanner.popkey() != "EN")
|
||||
{
|
||||
TMask_field* f = NULL;
|
||||
@ -1278,6 +1306,8 @@ void TMask::read_page(
|
||||
|
||||
if (is_toolbar && r.top ==0 && _toolbar != NULL_WIN)
|
||||
xvt_toolbar_realize(_toolbar);
|
||||
|
||||
scanner.pop_win();
|
||||
}
|
||||
|
||||
bool TMask::check_current_field() const
|
||||
@ -1297,8 +1327,6 @@ WINDOW TMask::create_book(bool single)
|
||||
WINDOW parent = 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);
|
||||
}
|
||||
if (single)
|
||||
|
@ -5,6 +5,10 @@
|
||||
#include <maskfld.h>
|
||||
#endif
|
||||
|
||||
#ifndef __STACK_H
|
||||
#include <stack.h>
|
||||
#endif
|
||||
|
||||
// Numero massimo di righe logiche per maschere
|
||||
#define MAX_MASK_ROWS 23
|
||||
|
||||
@ -29,6 +33,23 @@ enum TMaskmode {
|
||||
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
|
||||
|
||||
// @class TMask | Classe per la gestione delle maschere video
|
||||
@ -122,7 +143,7 @@ protected:
|
||||
// @cmember Inizializza la maschera
|
||||
void init_mask();
|
||||
// @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
|
||||
void set_tab_buttons(TToken_string& tabs);
|
||||
|
@ -646,7 +646,7 @@ const TString& TMask_field::get_default() const
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
const TString & TMask_field::evaluate_field(short id) const
|
||||
const TString& TMask_field::evaluate_field(short id) const
|
||||
{
|
||||
if (id == 0)
|
||||
return get();
|
||||
@ -2029,11 +2029,12 @@ word TEdit_field::class_id() const
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
RCT rect;
|
||||
get_rect(rect);
|
||||
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* b = NULL;
|
||||
const int pos = mask().id2pos(scanner.integer());
|
||||
if (pos >= 0)
|
||||
|
||||
short id = scanner.integer();
|
||||
if (id != 0)
|
||||
{
|
||||
const TMask_field& f = mask().fld(pos);
|
||||
if (f.is_edit())
|
||||
b = ((TEdit_field&)f).browse();
|
||||
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)
|
||||
{
|
||||
const TMask_field& f = m->fld(pos);
|
||||
if (f.is_edit())
|
||||
b = ((TEdit_field&)f).browse();
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
@ -2224,7 +2241,7 @@ bool TEdit_field::parse_item(TScanner& scanner)
|
||||
|
||||
if (scanner.key() == "CO") // Copyuse
|
||||
{
|
||||
const TString8 what(scanner.popkey());
|
||||
const TString8 what = scanner.popkey();
|
||||
const TBrowse* b = parse_browse(scanner);
|
||||
if (b)
|
||||
{
|
||||
|
@ -150,7 +150,9 @@ class TSpreadsheet : public TControl
|
||||
TBit_array _column_disabled;
|
||||
|
||||
// @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
|
||||
TMask _mask;
|
||||
@ -209,7 +211,7 @@ protected:
|
||||
|
||||
virtual void set_read_only(bool ro) { activate(!ro); }
|
||||
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;
|
||||
|
||||
//@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),
|
||||
_row_dirty(false), _cell_dirty(false), _check_enabled(true),
|
||||
_needs_update(-1), _selection_posted(-1), _ignore_button(0), _save_columns_order(false),
|
||||
_f9_target(NULL), _auto_append(false), _first_nav_column_id(-1),
|
||||
_last_nav_column_id(-1)
|
||||
_f9_target(NULL), _auto_append(false), _first_nav_column_id(-1),_last_nav_column_id(-1),
|
||||
_row_properties(NULL)
|
||||
{
|
||||
int m_width[MAX_COL], v_width[MAX_COL];
|
||||
int fixed_cols = 0; // Number of fixed columns
|
||||
@ -637,7 +639,9 @@ TSpreadsheet::TSpreadsheet(
|
||||
}
|
||||
|
||||
TSpreadsheet::~TSpreadsheet()
|
||||
{ }
|
||||
{
|
||||
delete _row_properties;
|
||||
}
|
||||
|
||||
TMask& TSpreadsheet::sheet_mask() const
|
||||
{ return ((TSpreadsheet*)this)->_mask; }
|
||||
@ -882,7 +886,7 @@ int TSpreadsheet::insert(
|
||||
TToken_string* toktok = new TToken_string(80, owner().separator());
|
||||
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
|
||||
owner().post_insert(r);
|
||||
@ -931,12 +935,12 @@ bool TSpreadsheet::destroy(
|
||||
if (rec < 0)
|
||||
{
|
||||
_str.destroy();
|
||||
_property.destroy();
|
||||
_properties.destroy();
|
||||
set_dirty(_row_dirty = false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_property.destroy(rec, true); // Destroy line info
|
||||
_properties.destroy(rec, true); // Destroy line info
|
||||
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)
|
||||
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)
|
||||
{
|
||||
TRow_property* prop = get_property(row, false);
|
||||
if (prop == NULL)
|
||||
prop = get_property(-1, false);
|
||||
if (prop != NULL)
|
||||
return prop->get(col, back, fore);
|
||||
return false;
|
||||
@ -2234,7 +2245,7 @@ void TSpreadsheet::swap_rows( const int fromindex, const int toindex)
|
||||
if (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.pack();
|
||||
|
||||
TObject* p = _property.remove(fromindex);
|
||||
_property.insert(p, toindex, true);
|
||||
_property.pack();
|
||||
TObject* p = _properties.remove(fromindex);
|
||||
_properties.insert(p, toindex, true);
|
||||
_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* p = (TRow_property*)_property.objptr(row);
|
||||
if (p == NULL && create)
|
||||
if (row < 0)
|
||||
{
|
||||
p = new TRow_property;
|
||||
_property.add(p, row);
|
||||
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;
|
||||
_properties.add(p, row);
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@ -3507,14 +3528,15 @@ TRectype* TSheet_field::putkey(const TRelation& r)
|
||||
// Certified: ...under debug..
|
||||
bool TSheet_field::autoload_line(int i, const TRectype& rec)
|
||||
{
|
||||
TMask& m = sheet_row_mask(i-1);
|
||||
TToken_string &row= this->row(i-1);
|
||||
|
||||
row.cut(0);
|
||||
for (short id = FIRST_FIELD; id <= _last_column_id; id++)
|
||||
{
|
||||
TMask_field& mf = sheet_mask().field(id);
|
||||
const TFieldref* dbfield = mf.field();
|
||||
|
||||
const TFieldref* dbfield = m.field(id).field();
|
||||
if (dbfield == NULL && m.id2pos(id+100) > 0) // Succede coi campi analitici
|
||||
dbfield = m.field(id+100).field();
|
||||
if (dbfield)
|
||||
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..
|
||||
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++)
|
||||
{
|
||||
TMask_field& mf = sheet_mask().field(id);
|
||||
const TFieldref* dbfield = mf.field();
|
||||
|
||||
const TFieldref* dbfield = m.field(id).field();
|
||||
if (dbfield == NULL && m.id2pos(id+100) > 0) // Succede coi campi analitici
|
||||
dbfield = m.field(id+100).field();
|
||||
if (dbfield)
|
||||
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
|
||||
destroy(); // cancella lo sheet
|
||||
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));
|
||||
|
||||
return(0);
|
||||
|
@ -28,7 +28,7 @@ void TPrintwin::paint_background(long j)
|
||||
TPrinter& pr = printer();
|
||||
const bool isbackground = _bg->items() > 0 && pr.isgraphics();
|
||||
const bool fink_mode = pr.get_fink_mode();
|
||||
int rw = (int)(j % _formlen);
|
||||
const int rw = (int)(j % _formlen);
|
||||
int cnt = 0; char ch;
|
||||
|
||||
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);
|
||||
// return;
|
||||
}
|
||||
if (!isbackground) return;
|
||||
|
||||
TString& rwd = (TString&)(*_bg)[rw];
|
||||
if (!isbackground)
|
||||
return;
|
||||
|
||||
const TString* rbg = (const TString*)_bg->objptr(rw);
|
||||
const TString& rwd = rbg ? *rbg : EMPTY_STRING;
|
||||
|
||||
while ((ch = rwd[cnt++]))
|
||||
{
|
||||
|
@ -419,7 +419,7 @@ bool TRelation_application::autonum(
|
||||
if (rec)
|
||||
((TEditable_field&)f).autosave(*get_relation());
|
||||
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();
|
||||
}
|
||||
@ -916,11 +916,11 @@ bool TRelation_application::test_key(
|
||||
word k, // @parm Chiave da ricercare
|
||||
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 = _mask->get_key_field(k, FALSE))
|
||||
e = _mask->get_key_field(k, false))
|
||||
{
|
||||
if (e->required() && e->shown())
|
||||
{
|
||||
@ -956,7 +956,7 @@ bool TRelation_application::test_key(
|
||||
{
|
||||
if (err)
|
||||
error_box(TR("Manca un valore indispensabile per la ricerca"));
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
return onefill || onereq;
|
||||
}
|
||||
@ -970,15 +970,17 @@ bool TRelation_application::find(word k)
|
||||
return test_key(1, TRUE);
|
||||
}
|
||||
|
||||
file().setkey(k);
|
||||
file().zero();
|
||||
for (TEditable_field* e = _mask->get_key_field(k, TRUE); e; e = _mask->get_key_field(k, FALSE))
|
||||
TRelation& rel = *get_relation();
|
||||
TLocalisamfile& fil = rel.file();
|
||||
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
|
||||
e->autosave(*get_relation());
|
||||
e->autosave(rel);
|
||||
}
|
||||
|
||||
const int err = file().read(_isequal);
|
||||
const int err = fil.read(_isequal);
|
||||
return err == NOERR;
|
||||
}
|
||||
|
||||
|
151
include/tree.cpp
151
include/tree.cpp
@ -7,7 +7,7 @@
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
void* p = NULL;
|
||||
if (node.not_empty())
|
||||
bool ok = goto_root();
|
||||
if (node.full())
|
||||
{
|
||||
#ifdef DBG_TREE
|
||||
if (!_expanded.is_key(node)) // Usa l'assoc array per testare i nodi validi!
|
||||
{
|
||||
NFCHECK("Invalid node: %s", (const char*)node);
|
||||
return goto_root();
|
||||
return false;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
@ -516,14 +522,13 @@ bool TObject_tree::goto_lbrother()
|
||||
|
||||
bool TObject_tree::set_object(TObject* obj)
|
||||
{
|
||||
if (_current)
|
||||
if (_current && _current->_obj != obj)
|
||||
{
|
||||
#ifdef DBG_TREE
|
||||
TString str; curr_id(str);
|
||||
_expanded.add(str); // Usa l'assoc array per memorizzare i nodi validi!
|
||||
#endif
|
||||
if (_current->_obj)
|
||||
delete _current->_obj;
|
||||
delete detach_object();
|
||||
_current->_obj = obj;
|
||||
}
|
||||
return _current != NULL;
|
||||
@ -542,6 +547,92 @@ bool TObject_tree::set_object(const TObject& obj)
|
||||
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()
|
||||
{
|
||||
if (!has_root())
|
||||
@ -604,10 +695,15 @@ bool TObject_tree::add_rbrother(TObject* obj)
|
||||
bool ok = false;
|
||||
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;
|
||||
newbrother->_father = _current->_father;
|
||||
newbrother->_lbrother = _current;
|
||||
newbrother->_rbrother = _current->_rbrother;
|
||||
if (_current->_rbrother != NULL)
|
||||
{
|
||||
newbrother->_rbrother = _current->_rbrother;
|
||||
_current->_rbrother->_lbrother = newbrother;
|
||||
}
|
||||
_current->_rbrother = newbrother;
|
||||
ok = goto_rbrother();
|
||||
}
|
||||
@ -630,19 +726,20 @@ bool TObject_tree::add_rbrother(const 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 (_current->_lbrother == NULL)
|
||||
ok = add_brother(obj);
|
||||
if (goto_lbrother())
|
||||
ok = add_rbrother(obj);
|
||||
else
|
||||
{
|
||||
TTree_node* newbrother = new TTree_node;
|
||||
newbrother->_father = _current->_father;
|
||||
newbrother->_rbrother = _current;
|
||||
newbrother->_lbrother = _current->_lbrother;
|
||||
_current->_lbrother = newbrother;
|
||||
ok = goto_lbrother();
|
||||
_current->_lbrother = newbrother;
|
||||
if (_current->_father != NULL)
|
||||
_current->_father->_son = newbrother;
|
||||
_current = newbrother;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -718,6 +815,18 @@ bool TObject_tree::get_description(TString& str) const
|
||||
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()
|
||||
{
|
||||
_root = _current = NULL;
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
virtual bool goto_rbrother() pure;
|
||||
virtual bool goto_node(const TString &id) pure;
|
||||
virtual TObject* curr_node() const pure;
|
||||
|
||||
virtual int curr_depth() const;
|
||||
virtual bool has_root() const;
|
||||
virtual bool has_father() const;
|
||||
virtual bool could_have_son() const; // Is not terminal node
|
||||
@ -112,6 +112,7 @@ class TObject_tree : public TBidirectional_tree
|
||||
TTree_node *_root, *_current;
|
||||
|
||||
bool create_root(); // Internal use only
|
||||
void reparent(TObject_tree::TTree_node* son1, TObject_tree::TTree_node* father);
|
||||
|
||||
protected:
|
||||
virtual void node2id(const TObject* node, TString& id) const;
|
||||
@ -141,6 +142,7 @@ public: // TTree
|
||||
virtual bool expanded() const;
|
||||
|
||||
public: // TBidirectional_tree
|
||||
virtual int curr_depth() const;
|
||||
virtual bool has_father() const { return _current && _current->_father; }
|
||||
virtual bool has_lbrother() const { return _current && _current->_lbrother; }
|
||||
virtual bool goto_father();
|
||||
@ -151,6 +153,13 @@ public: // TBidirectional_tree
|
||||
public:
|
||||
bool set_object(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();
|
||||
|
||||
TObject_tree();
|
||||
|
@ -354,9 +354,18 @@ void TTree_window::set_tree(TTree* tree)
|
||||
if (_tree != NULL)
|
||||
{
|
||||
// Memorizza la posizione dell'albero per dopo ...
|
||||
TString curr; tree->curr_id(curr);
|
||||
create_children(NULL); // Rigenera i figli della radice
|
||||
if (tree->goto_node(curr)) // Riporta la selezione sul nodo memorizzato
|
||||
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
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -621,6 +630,7 @@ void TTree_field::set_tree(TTree* tree)
|
||||
TTree_window& tv = tree_win();
|
||||
tv.set_tree(tree);
|
||||
}
|
||||
|
||||
void TTree_field::force_update()
|
||||
{ set_tree(tree()); }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user