2017-04-21 01:33:36 +00:00
# include <colors.h>
# include <mailbox.h>
# include <msksheet.h>
# include <postman.h>
# include <progind.h>
# include <sheet.h>
# include <recarray.h>
# include <relapp.h>
# include <statbar.h>
# include <urldefid.h>
# include <utility.h>
///////////////////////////////////////////////////////////
// TRelation_application
///////////////////////////////////////////////////////////
TRelation_application : : TRelation_application ( )
: _mask ( NULL ) , _search_id ( - 1 ) , _lnflag ( 0 ) ,
_autodelete ( 0 ) , _navigating ( false ) ,
_locked ( false )
{ }
TRelation_application : : ~ TRelation_application ( )
{ }
bool TRelation_application : : has_filtered_cursor ( ) const
{
bool yes = filtered ( ) ;
if ( yes )
{
const TEdit_field & f = get_search_field ( ) ;
yes = f . browse ( ) ! = NULL ;
}
return yes ;
}
TCursor * TRelation_application : : get_filtered_cursor ( ) const
{
if ( has_filtered_cursor ( ) )
{
const TEdit_field & f = get_search_field ( ) ;
return f . browse ( ) - > cursor ( ) ;
}
else
return NULL ;
}
void TRelation_application : : setkey ( )
{
if ( has_filtered_cursor ( ) )
get_filtered_cursor ( ) - > setkey ( ) ;
else
file ( ) . setkey ( 1 ) ;
}
void TRelation_application : : set_key_filter ( )
{
TString rf = get_user_read_filter ( ) ; rf . trim ( ) ;
if ( rf . not_empty ( ) )
{
TString expr ;
for ( int f = _mask - > fields ( ) - 1 ; f > = 0 ; f - - )
{
TMask_field & fld = _mask - > fld ( f ) ;
if ( fld . is_edit ( ) & & fld . in_key ( 0 ) )
{
TBrowse * b = ( ( TEdit_field & ) fld ) . browse ( ) ;
if ( b & & b - > cursor ( ) - > relation ( ) - > lfile ( ) . num ( ) = = get_relation ( ) - > lfile ( ) . num ( ) )
{
expr = b - > get_filter ( ) ;
if ( expr . find ( rf ) < 0 )
{
if ( expr . not_empty ( ) )
{
expr . insert ( " ( " , 0 ) ;
expr < < " )&&( " < < rf < < ' ) ' ;
}
else
expr = rf ;
b - > set_filter ( expr ) ;
}
}
}
}
}
}
// @doc INTERNAL
// @mfunc Setta i limiti
void TRelation_application : : set_limits (
byte what ) // @parm tipo di limite da assegnare al record
// @comm I limiti possibili sono:
// @flag 0 | Nessuna operazione
// @flag 1 | Primo record
// @flag 2 | Ultimo record
// @flag 3 | Entrambi
{
if ( has_filtered_cursor ( ) )
{
const TEdit_field & f = get_search_field ( ) ;
if ( f . browse ( ) ! = NULL )
f . browse ( ) - > do_input ( true ) ;
TCursor * cur = get_filtered_cursor ( ) ;
cur - > setkey ( ) ;
if ( cur - > items ( ) > 0 )
{
TBaseisamfile & f = cur - > file ( ) ;
if ( what & 0x1 )
{
* cur = 0 ;
_first = f . recno ( ) ;
}
if ( what & 0x2 )
{
* cur = cur - > items ( ) - 1 ;
_last = f . recno ( ) ;
}
}
else
_first = _last = - 1 ;
}
else
{
setkey ( ) ;
TBaseisamfile & f = file ( ) ;
if ( ! f . empty ( ) )
{
if ( what & 0x1 )
{
if ( f . first ( ) = = NOERR )
_first = f . recno ( ) ;
}
if ( what & 0x2 )
{
if ( f . last ( ) = = NOERR )
_last = f . recno ( ) ;
}
}
else
_first = _last = - 1 ;
}
}
void TRelation_application : : set_find_button ( )
{
// Ricalcola posizioni bootoni di navigazione con la vecchia toolbar
WINDOW bar = _mask - > toolbar ( ) ;
if ( bar ! = NULL_WIN )
xvt_toolbar_realize ( _mask - > toolbar ( ) ) ;
else // Non c'e' la nuova relapbar
{
int pos = _mask - > id2pos ( DLG_FINDREC ) ;
if ( pos > = 0 & & _mask - > id2pos ( DLG_FIRSTREC ) > = 0 ) //se e' un bottone pentapartito...
{
TButton_field & f_find = ( TButton_field & ) _mask - > fld ( pos ) ;
RCT rct_base ; f_find . get_rect ( rct_base ) ;
const int bwidth = ( rct_base . right - rct_base . left ) ;
const int bheight = ( rct_base . bottom - rct_base . top ) ;
if ( bwidth > 3 * bheight / 2 ) // Controllo se ho gia' ridimensionato i bottoni in precedenza
{
int bx = bwidth / 3 ;
int by = bheight / 2 ;
RCT r = rct_base ;
r . left + = bx ; r . right - = bx ;
if ( ! NATIVE_CONTROLS )
{
r . left - = 2 ; r . right + = 2 ;
}
f_find . set_rect ( r ) ; // Ridimensiona il bottone centrale di ricerca
if ( ! NATIVE_CONTROLS )
{
bx + = 5 ; by + = 3 ; // Aggiusta dimensioni bottoni sussidiari
}
pos = _mask - > id2pos ( DLG_FIRSTREC ) ;
if ( pos > = 0 )
{
r = rct_base ; r . top = r . bottom - by ; r . right = r . left + bx ;
_mask - > fld ( pos ) . set_rect ( r ) ;
}
pos = _mask - > id2pos ( DLG_PREVREC ) ;
if ( pos > = 0 )
{
r = rct_base ; r . bottom = r . top + by ; r . right = r . left + bx ;
_mask - > fld ( pos ) . set_rect ( r ) ;
}
pos = _mask - > id2pos ( DLG_NEXTREC ) ;
if ( pos > = 0 )
{
r = rct_base ; r . bottom = r . top + by ; r . left = r . right - bx ;
_mask - > fld ( pos ) . set_rect ( r ) ;
}
pos = _mask - > id2pos ( DLG_LASTREC ) ;
if ( pos > = 0 )
{
r = rct_base ; r . top = r . bottom - by ; r . left = r . right - bx ;
_mask - > fld ( pos ) . set_rect ( r ) ;
}
}
}
}
}
bool TRelation_application : : create ( )
{
bool ok = user_create ( ) ;
if ( ok )
{
write_enable ( ) ;
_mask = get_mask ( MODE_QUERY ) ;
filter ( ) ;
set_key_filter ( ) ;
set_limits ( ) ;
}
return ok ? TSkeleton_application : : create ( ) : ok ;
}
bool TRelation_application : : destroy ( )
{
user_destroy ( ) ;
return TSkeleton_application : : destroy ( ) ;
}
void TRelation_application : : set_fixed ( )
{
TToken_string s ( 256 , ' = ' ) ;
FOR_EACH_TOKEN ( _fixed , f )
{
s = f ;
const short id = s . get_int ( 0 ) ;
if ( id > 0 & & _mask - > id2pos ( id ) > = 0 )
{
s = s . get ( ) ;
if ( s . not_empty ( ) )
_mask - > set ( id , s ) ;
if ( _lnflag < 2 )
_mask - > disable ( id ) ;
}
}
}
void TRelation_application : : enable_query ( )
{
const bool query = _mask - > query_mode ( ) ;
const bool keyon = query | | get_relation ( ) - > status ( ) = = _isreinsert ;
for ( int i = _mask - > fields ( ) - 1 ; i > = 0 ; i - - )
{
TMask_field & c = _mask - > fld ( i ) ;
if ( c . in_key ( 0 ) & & c . enabled_default ( ) )
{
if ( c . in_key ( 1 ) )
c . enable ( keyon ) ;
if ( c . is_edit ( ) )
{
TEdit_field & e = ( TEdit_field & ) c ;
if ( e . browse ( ) ! = NULL )
e . enable_check ( query ) ;
}
}
}
set_fixed ( ) ;
}
bool TRelation_application : : can_I_write ( const TRelation * rel ) const
{ return ! _locked & & user_can_write ( rel ) ; }
bool TRelation_application : : can_I_read ( const TRelation * rel ) const
{ return user_can_read ( rel ) ; }
void TRelation_application : : set_toolbar ( )
{
const int mode = _mask - > mode ( ) ;
const bool can_edit_some = can_I_write ( NULL ) ;
const bool can_nav = _lnflag = = 0 & & _curr_transaction ! = TRANSACTION_LINK ;
bool enabsave = can_edit_some ;
int pos = _mask - > id2pos ( DLG_SAVEREC ) ;
if ( pos > = 0 )
{
enabsave = can_edit_some & & ( mode ! = MODE_QUERY ) & & can_I_write ( get_relation ( ) ) ;
_mask - > fld ( pos ) . enable ( enabsave ) ;
}
pos = _mask - > id2pos ( DLG_DELREC ) ;
if ( pos > = 0 )
{
bool enabdel = can_edit_some & & ( mode = = MODE_QUERY | | mode = = MODE_MOD ) ;
if ( enabdel & & mode = = MODE_MOD )
{
TRelation & r = * get_relation ( ) ;
const TRecnotype oldpos = r . lfile ( ) . recno ( ) ;
enabdel = enabsave & & ! protected_record ( r ) & & user_can_delete ( & r ) ;
if ( r . lfile ( ) . recno ( ) ! = oldpos )
r . lfile ( ) . readat ( oldpos ) ;
}
_mask - > fld ( pos ) . enable ( enabdel ) ;
}
pos = _mask - > id2pos ( DLG_FINDREC ) ;
if ( pos > = 0 )
{
_mask - > fld ( pos ) . enable ( _lnflag = = 0 ) ;
const long recno = get_relation ( ) - > lfile ( ) . recno ( ) ;
const bool enable_next_prev = _mask - > edit_mode ( ) ;
pos = _mask - > id2pos ( DLG_FIRSTREC ) ;
if ( pos > = 0 )
_mask - > fld ( pos ) . enable ( can_nav & & ( enable_next_prev ? _first ! = recno : _first > 0 ) ) ;
pos = _mask - > id2pos ( DLG_PREVREC ) ;
if ( pos > = 0 )
_mask - > fld ( pos ) . enable ( can_nav & & enable_next_prev & & _first > 0 & & _first ! = recno ) ;
pos = _mask - > id2pos ( DLG_NEXTREC ) ;
if ( pos > = 0 )
_mask - > fld ( pos ) . enable ( can_nav & & enable_next_prev & & _last > 0 & & _last ! = recno ) ;
pos = _mask - > id2pos ( DLG_LASTREC ) ;
if ( pos > = 0 )
_mask - > fld ( pos ) . enable ( can_nav & & ( enable_next_prev ? _last ! = recno : _last > 0 ) ) ;
}
pos = _mask - > id2pos ( DLG_NEWREC ) ;
if ( pos > = 0 )
{
2017-06-16 14:52:02 +00:00
// Prima: can_edit_some = can_I_write(NULL)
// Adesso: user_can_write() -> a me interessa che l'utente possa scrivere senza controllare che sia bloccato il record, si pu<70> sempre creare un record (se abilitati) nuovo anche in visualizzazione
bool enabins = ( mode = = MODE_QUERY | | _lnflag = = 0 ) & & user_can_write ( NULL ) ;
2017-04-21 01:33:36 +00:00
_mask - > fld ( pos ) . enable ( enabins ) ;
}
set_find_button ( ) ;
enable_query ( ) ;
}
void TRelation_application : : update_navigation_bar ( )
{
if ( _mask - > query_mode ( ) )
{
set_limits ( ) ;
set_toolbar ( ) ;
}
}
bool TRelation_application : : save_and_new ( ) const
{ return false ; }
bool TRelation_application : : save_and_quit ( ) const
{
return ( _autoins_caller . full ( ) | | _curr_transaction . not_empty ( ) ) & & _curr_trans_mode ! = TM_REMAIN ;
}
int TRelation_application : : set_mode ( int mode )
{
static int _mode = NO_MODE ;
if ( mode < NO_MODE ) mode = _mode ;
const int m = ( ( TMaskmode ) mode = = NO_MODE ) ? ( int ) MODE_QUERY : mode ;
_mask - > set_mode ( m ) ;
set_toolbar ( ) ;
_mode = mode ;
const char * t = " " ;
switch ( mode )
{
case MODE_QUERY :
t = TR ( " Ricerca " ) ; break ;
case MODE_MOD :
t = TR ( " Modifica " ) ; break ;
case NO_MODE :
t = TR ( " Ricerca/Inserimento " ) ; break ;
case MODE_INS :
t = TR ( " Inserimento " ) ; break ;
default :
break ;
}
xvtil_statbar_set ( t , TRUE ) ;
return _mode ;
}
// @doc INTERNAL
// @mfunc Permette di autonumerare un record
//
// @rdesc Ritorna se e' riuscito a creare una nuova autonumerazione:
//
// @flag TRUE | La chiave non e' vuota
// @flag FALSE | Non e' riuscito ad autonumerare il documento
bool TRelation_application : : autonum (
TMask * m , // @parm Maschera a cui applicare l'autonumerazione
bool rec ) // @parm Indica se registrare la chiave anche sul record corrente
{
TToken_string k ;
if ( ! get_next_key ( k ) )
{
k = get_next_key ( ) ;
# ifdef DBG
if ( k . full ( ) )
xvt_dm_popup_warning ( " 'const char* get_next_key()' is deprecated: implement 'bool get_next_key(TToken_string&)' " ) ;
# endif
}
if ( ! rec & & ! m - > query_mode ( ) )
m - > reset ( ) ;
_renum_message = " " ;
for ( const char * n = k . get ( 0 ) ; n & & * n ; n = k . get ( ) )
{
TMask_field * fld = NULL ;
if ( isdigit ( * n ) )
fld = m - > find_by_id ( atoi ( n ) ) ;
else
fld = m - > find_by_fieldname ( n ) ;
if ( fld = = NULL )
{
NFCHECK ( " Identificatore di autonumerazione errato " ) ;
return false ;
}
const char * val = k . get ( ) ;
TMask_field & f = * fld ;
if ( rec | | f . empty ( ) )
f . set ( val ) ;
if ( rec )
( ( TEditable_field & ) f ) . autosave ( * get_relation ( ) ) ;
if ( _renum_message . empty ( ) | | f . in_key ( 1 ) )
_renum_message . format ( FR ( " L'elemento <20> stato registrato con: \n %s = %s " ) ,
( const char * ) f . prompt ( ) , ( const char * ) f . get ( ) ) ;
}
return k . full ( ) ;
}
// @doc EXTERNAL
// @mfunc Entra in modo di ricerca
void TRelation_application : : query_mode (
bool pre_ins ) // @parm Indica in quale modo andare:
//
// @flag TRUE | Entra in modo MODE_QUERY_INSERT
// @flag FALSE | Entra in modo MODE_QUERY (default)
{
TMask * old = _mask ;
const bool was_open = old ! = NULL & & old - > is_open ( ) ;
const bool changing = changing_mask ( MODE_QUERY ) ;
if ( changing & & was_open )
old - > close_modal ( ) ;
_mask = get_mask ( MODE_QUERY ) ;
if ( changing )
{
if ( was_open )
_mask - > open_modal ( ) ;
set_limits ( ) ;
}
_mask - > set_mode ( pre_ins ? MODE_QUERYINS : MODE_QUERY ) ;
_mask - > reset ( ) ;
_mask - > disable_page ( 1 ) ; // Nasconde pagine inutili
if ( pre_ins )
{
set_mode ( NO_MODE ) ;
init_query_insert_mode ( * _mask ) ;
enable_query ( ) ;
}
else
{
set_mode ( MODE_QUERY ) ;
init_query_mode ( * _mask ) ;
enable_query ( ) ;
// Aggiorna bottoni di ricerca: utile soprattutto per ve0 che imposta CODNUM
if ( has_filtered_cursor ( ) )
{
set_limits ( ) ;
set_toolbar ( ) ;
}
}
}
void TRelation_application : : insert_mode ( )
{
bool try_auto = true ;
if ( _mask - > query_mode ( ) )
try_auto = ! test_key ( 1 , FALSE ) ;
if ( try_auto & & ! autonum ( _mask , FALSE ) )
{
query_insert_mode ( ) ;
return ;
}
TRelation * r = get_relation ( ) ;
r - > zero ( ) ;
_mask - > autosave ( * r ) ;
if ( ! can_I_write ( r ) )
{
warning_box ( FR ( " L'utente %s non puo' inserire %s " ) , ( const char * ) user ( ) , r - > file ( ) . description ( ) ) ;
return ;
}
const bool changing = changing_mask ( MODE_INS ) ;
TFilename workname ; workname . temp ( " msk " ) ;
if ( changing )
{
_mask - > set_workfile ( workname ) ;
_mask - > save ( ) ;
_mask - > close_modal ( ) ;
}
_mask = get_mask ( MODE_INS ) ;
if ( changing )
{
_mask - > reset ( ) ;
_mask - > set_workfile ( workname ) ;
_mask - > load ( ) ;
xvt_fsys_remove_file ( workname ) ;
_mask - > open_modal ( ) ;
}
else
_mask - > enable_page ( 1 ) ;
set_mode ( MODE_INS ) ;
r - > zero ( ) ; // Azzera tutta la relazione!
_mask - > load_defaults ( ) ;
init_insert_mode ( * _mask ) ;
// ....possibilmente spostare questa chiamata .....
if ( is_transaction ( ) & & _curr_transaction = = TRANSACTION_INSERT )
ini2insert_mask ( ) ;
}
bool TRelation_application : : modify_mode ( )
{
TRelation * rel = get_relation ( ) ;
const TReclock block = can_I_write ( rel ) ? _testandlock : _nolock ;
int err = rel - > read ( _isequal , block ) ;
if ( ! can_I_read ( rel ) )
{
warning_box ( TR ( " I dati non sono accessibili per l'utente %s " ) , ( const char * ) user ( ) ) ;
query_mode ( ) ;
return FALSE ;
}
_locked = false ;
if ( err ! = NOERR )
{
if ( err = = _islocked )
{
_locked = true ;
message_box ( TR ( " I dati sono gi<67> usati da un altro programma, scrittura disabilitata " ) ) ;
}
else
{
error_box ( FR ( " Impossibile leggere i dati: errore %d " ) , err ) ;
if ( ! is_transaction ( ) )
query_mode ( ) ;
return false ;
}
}
const bool changing = changing_mask ( MODE_MOD ) ;
if ( changing )
_mask - > close_modal ( ) ;
_mask = get_mask ( MODE_MOD ) ;
if ( changing )
_mask - > open_modal ( ) ;
else
_mask - > enable_page ( 1 ) ;
set_mode ( MODE_MOD ) ;
err = read ( * _mask ) ;
2017-06-16 14:52:02 +00:00
if ( err ! = NOERR & & ( ! _locked | | err ! = _islocked ) )
2017-04-21 01:33:36 +00:00
{
query_mode ( ) ;
2017-06-16 14:52:02 +00:00
return false ;
2017-04-21 01:33:36 +00:00
}
rel - > save_status ( ) ;
init_modify_mode ( * _mask ) ;
// ....possibilmente spostare questa chiamata .....
// Forse deve essere fatta prima della init_modify_mode()!
if ( _curr_transaction = = TRANSACTION_MODIFY )
ini2insert_mask ( ) ;
2017-06-16 14:52:02 +00:00
return true ;
2017-04-21 01:33:36 +00:00
}
TEdit_field & TRelation_application : : get_search_field ( ) const
{
short id = _search_id ;
if ( id < = 0 | | ! _mask - > field ( id ) . shown ( ) )
{
for ( int i = _mask - > fields ( ) - 1 ; i > = 0 ; i - - )
{
const TMask_field & f = _mask - > fld ( i ) ;
if ( f . is_edit ( ) & & f . in_key ( 1 ) & & f . shown ( ) )
{
id = f . dlg ( ) ;
break ;
}
}
}
return _mask - > efield ( id ) ;
}
bool TRelation_application : : search_mode ( )
{
if ( _mask - > mode ( ) ! = MODE_QUERY )
query_mode ( ) ;
TEdit_field * prima = & get_search_field ( ) ;
while ( prima )
{
if ( prima - > on_key ( K_F9 ) )
{
if ( find ( 1 ) )
return modify_mode ( ) ;
else
break ;
}
TMask_field * dopo = & _mask - > focus_field ( ) ;
if ( dopo ! = prima & & dopo - > is_edit ( ) & & dopo - > in_key ( 0 ) )
prima = ( TEdit_field * ) dopo ;
else
break ;
}
return false ;
}
HIDDEN bool delete_handler ( TMask_field & f , KEY k )
{
if ( k = = K_TAB & & f . focusdirty ( ) & & ! f . empty ( ) )
{
TMask & m = f . mask ( ) ;
const bool finale = * f . prompt ( ) = = ' A ' ;
const int pos = m . id2pos ( f . dlg ( ) ) ;
if ( pos > = 3 )
{
const TMask_field & e = m . fld ( pos - 3 ) ;
if ( e . is_edit ( ) & & e . get ( ) . blank ( ) )
{
const short id = e . dlg ( ) - ( finale ? 200 : 100 ) ;
const TRelation_application & app = ( TRelation_application & ) main_app ( ) ;
const TMask_field & orig = app . curr_mask ( ) . field ( id ) ;
bool req = orig . required ( ) ;
if ( ! req & & orig . is_edit ( ) )
{
const TEdit_field & e = ( TEdit_field & ) orig ;
req = e . validate_func ( ) = = 12 ;
}
if ( req )
{
TString str ; str < < ( finale ? TR ( " A " ) : TR ( " Da " ) ) < < orig . prompt ( ) ;
return f . error_box ( FR ( " Specificare anche il valore %s " ) , ( const char * ) str ) ;
}
}
}
if ( finale & & ! f . get ( ) . blank ( ) )
{
const TMask_field & p = m . fld ( pos - 1 ) ;
TString80 prec = p . get ( ) ;
TString80 curr = f . get ( ) ;
bool ok ;
switch ( p . class_id ( ) )
{
case CLASS_REAL_FIELD : ok = real ( prec ) < = real ( curr ) ; break ;
case CLASS_DATE_FIELD : ok = TDate ( prec ) < = TDate ( curr ) ; break ;
default : ok = prec < = curr ; break ;
}
if ( ! ok )
return f . error_box ( FR ( " Inserire un valore non inferiore a '%s' " ) , ( const char * ) prec ) ;
}
}
return TRUE ;
}
int TRelation_application : : delete_mode ( )
{
TEdit_field & fld = get_search_field ( ) ;
TBrowse * brw = fld . browse ( ) ;
if ( brw )
{
brw - > do_input ( TRUE ) ;
TCursor & cur = * brw - > cursor ( ) ;
TToken_string head ( brw - > head ( ) ) ;
head . insert ( " @1| " , 0 ) ;
TToken_string items ( brw - > items ( ) ) ;
items . insert ( " | " , 0 ) ;
int tab1 = 0 , tab2 = 0 , y = 0 ;
// Nuovo modo basato sugli input
TToken_string inplist = brw - > get_input_fields ( ) ;
if ( inplist . not_empty ( ) )
{
FOR_EACH_TOKEN ( inplist , tok )
{
if ( * tok ! = ' " ' & & strchr ( tok , ' @ ' ) = = NULL )
{
TMask_field & e = _mask - > field ( short ( atoi ( tok ) ) ) ;
if ( e . active ( ) )
{
const int len = strlen ( e . prompt ( ) ) ;
if ( len > tab1 ) tab1 = len ;
const int size = e . size ( ) ;
if ( size > tab2 ) tab2 = size ;
y + + ;
}
}
}
}
tab1 + = 5 ;
tab2 + = tab1 + 2 ;
cur = 0L ;
TCursor_sheet sht ( & cur , items , TR ( " Eliminazione " ) , head , 0x4 , y ) ;
y = - 1 ; // Posizione del campo precedente
TString prompt ; // Prompt del campo corrente
const short delta = 100 ;
FOR_EACH_TOKEN ( inplist , tok )
{
if ( * tok ! = ' " ' & & strchr ( tok , ' @ ' ) = = NULL )
{
TMask_field & e = _mask - > field ( short ( atoi ( tok ) ) ) ;
if ( ! e . active ( ) )
continue ;
const short id = e . dlg ( ) + delta ;
prompt = " Da " ; prompt < < e . prompt ( ) ;
sht . add_static ( DLG_NULL , 0 , prompt , 1 , + + y ) ;
TString16 flags ;
if ( e . automagic ( ) ) flags < < ' A ' ;
if ( e . roman ( ) ) flags < < ' M ' ;
if ( e . right_justified ( ) ) flags < < ' R ' ;
if ( e . uppercase ( ) ) flags < < ' U ' ;
if ( e . zerofilled ( ) ) flags < < ' Z ' ;
switch ( e . class_id ( ) )
{
case CLASS_DATE_FIELD :
{
TDate_field & d1 = sht . add_date ( id , 0 , " " , tab1 , y , flags ) ;
TDate_field & d2 = sht . add_date ( id + delta , 0 , " A " , tab2 , y , flags ) ;
d1 . set_handler ( delete_handler ) ;
d2 . set_handler ( delete_handler ) ;
}
break ;
case CLASS_REAL_FIELD :
{
TReal_field & r1 = sht . add_number ( id , 0 , " " , tab1 , y , e . size ( ) , flags ) ;
TReal_field & r2 = sht . add_number ( id + delta , 0 , " A " , tab2 , y , e . size ( ) , flags ) ;
r1 . set_handler ( delete_handler ) ;
r2 . set_handler ( delete_handler ) ;
}
break ;
default :
{
TEdit_field & e1 = sht . add_string ( id , 0 , " " , tab1 , y , e . size ( ) , flags ) ;
TEdit_field & e2 = sht . add_string ( id + delta , 0 , " A " , tab2 , y , e . size ( ) , flags ) ;
e1 . set_handler ( delete_handler ) ;
e2 . set_handler ( delete_handler ) ;
}
break ;
}
if ( y = = 0 )
sht . first_focus ( id ) ;
}
}
sht . open_modal ( ) ;
KEY tasto ;
bool keep_running = TRUE ;
while ( keep_running )
{
tasto = sht . run ( ) ;
if ( tasto = = K_ENTER )
{
TRectype rec_from ( cur . curr ( ) ) , rec_to ( cur . curr ( ) ) ;
rec_from . zero ( ) ; rec_to . zero ( ) ;
TToken_string fldlist = brw - > get_input_field_names ( ) ;
TString80 str ;
int fi = 0 ;
for ( TString80 tok = inplist . get ( fi ) ; tok . not_empty ( ) ; tok = inplist . get ( ) , fi + + )
{
const TString16 fn = fldlist . get ( fi ) ;
const TFieldref fr ( fn , 0 ) ;
if ( * tok = = ' " ' )
{
str = tok ;
str . ltrim ( 1 ) ; str . rtrim ( 1 ) ;
fr . write ( str , rec_from ) ;
fr . write ( str , rec_to ) ;
}
else
{
const short id = short ( atoi ( tok ) ) ;
if ( sht . id2pos ( id + delta ) > = 0 )
{
str = sht . get ( id + delta ) ;
if ( str . not_empty ( ) )
fr . write ( str , rec_from ) ;
str = sht . get ( id + 2 * delta ) ;
if ( str . not_empty ( ) )
fr . write ( str , rec_to ) ;
}
else
{
str = _mask - > get ( id ) ;
fr . write ( str , rec_from ) ;
fr . write ( str , rec_to ) ;
}
}
}
if ( rec_from . empty ( ) & & rec_to . empty ( ) )
{
sht . check ( - 1 ) ;
}
else
{
const long totit = cur . items ( ) ;
cur . freeze ( TRUE ) ;
cur . curr ( ) = rec_from ;
cur . read ( ) ;
while ( cur . pos ( ) < totit & & cur . curr ( ) < = rec_to )
{
sht . check ( cur . pos ( ) ) ;
+ + cur ;
}
cur . freeze ( FALSE ) ;
}
}
else
{
keep_running = FALSE ;
if ( tasto = = K_DEL & & sht . checked ( ) = = 0 )
{
error_box ( TR ( " Non <20> stato selezionato nessun elemento " ) ) ;
sht . select ( 0 ) ;
keep_running = TRUE ;
}
}
}
sht . close_modal ( ) ;
if ( tasto = = K_DEL )
{
long deleting = sht . checked ( ) ;
TString msg ;
msg . format ( FR ( " Confermare l'eliminazione di %d elementi " ) , deleting ) ;
bool can_delete = delete_box ( msg ) ;
if ( can_delete & & deleting > 100 )
{
msg . insert ( TR ( " ATTENZIONE: " ) , 0 ) ;
can_delete = delete_box ( msg ) ;
}
if ( can_delete )
{
TWait_cursor hourglass ;
long skipped = 0 ; // Record non cancellati perche' protetti
cur . freeze ( TRUE ) ; // Congelo il cursore altrimenti si riaggiorna troppo
for ( long pos = sht . items ( ) - 1 ; deleting > 0 ; pos - - )
{
if ( sht . checked ( pos ) )
{
cur = pos ;
brw - > do_output ( ) ;
bool can_delete = FALSE ;
if ( find ( 1 ) )
{
TRelation & r = * get_relation ( ) ;
_autodelete = 0x3 ;
if ( ! protected_record ( r ) )
{
if ( modify_mode ( ) )
{
r . restore_status ( ) ;
can_delete = remove ( ) ;
}
cur . freeze ( false ) ;
query_mode ( ) ;
cur . freeze ( true ) ;
}
_autodelete = FALSE ;
}
if ( ! can_delete )
skipped + + ;
deleting - - ;
}
}
cur . freeze ( FALSE ) ;
set_limits ( ) ; // Riaggiorno il numero del primo/ultimo record
if ( skipped > 0 )
{
warning_box ( FR ( " %ld elementi non sono stati cancellati in quanto protetti. " ) , skipped ) ;
query_mode ( ) ;
}
}
}
}
else
{
if ( search_mode ( ) )
_autodelete = TRUE ;
}
return TRUE ;
}
// @doc INTERNAL
// @mfunc Controlla se una chiave e' completa ed esiste su file
//
// @rdesc Ritorna se la chave esiste sul file
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 ;
for ( TEditable_field * e = _mask - > get_key_field ( k , true ) ;
e ! = NULL ;
e = _mask - > get_key_field ( k , false ) )
{
if ( e - > required ( ) & & e - > shown ( ) )
{
onereq = TRUE ;
if ( e - > empty ( ) )
{
if ( err )
{
TString msg ( 80 ) ;
msg = TR ( " Manca un valore indispensabile per la ricerca. " ) ;
# ifdef DBG
msg < < " \n Chiave " < < int ( k ) < < " - Campo " < < e - > dlg ( ) ;
const TFieldref * fr = e - > field ( ) ;
if ( fr ! = NULL )
{
msg < < " - " < < fr - > name ( ) ;
if ( fr - > to ( ) > 0 )
msg < < ' [ ' < < fr - > from ( ) < < ' , ' < < fr - > to ( ) < < ' ] ' ;
}
# endif
error_box ( msg ) ;
_mask - > first_focus ( - e - > dlg ( ) ) ;
}
return FALSE ;
}
}
else
/* if (k == 1 && !onereq && !onefill && c.get().not_empty()) */
if ( ! onereq & & ! onefill & & e - > is_edit ( ) & & ! e - > empty ( ) )
onefill = TRUE ;
}
if ( k = = 1 & & ! onereq & & ! onefill )
{
if ( err )
error_box ( TR ( " Manca un valore indispensabile per la ricerca " ) ) ;
return false ;
}
return onefill | | onereq ;
}
bool TRelation_application : : find ( word k )
{
if ( k = = 0 )
{
for ( k = 1 ; k < = MAX_KEYS & & ! test_key ( k , FALSE ) ; k + + ) ;
if ( k > MAX_KEYS )
return test_key ( 1 , TRUE ) ;
}
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 ( rel ) ;
}
const int err = fil . read ( _isequal ) ;
return err = = NOERR ;
}
void TRelation_application : : edit_cancel ( )
{
if ( _mask - > mode ( ) = = MODE_MOD )
{
TRelation * rel = get_relation ( ) ;
rel - > restore_status ( ) ;
2017-06-16 14:52:02 +00:00
_locked = false ;
rel - > lfile ( ) . reread ( _unlock ) ; // Unlock main file
2017-04-21 01:33:36 +00:00
}
}
short TRelation_application : : mask_field_dirty ( ) const
{
short id = 0 ;
if ( _mask )
{
const int mode = _mask - > mode ( ) ;
if ( mode = = MODE_QUERY )
{
FOR_EACH_MASK_FIELD ( * _mask , i , f )
{
if ( f - > dirty ( ) & & f - > active ( ) )
{
id = f - > dlg ( ) ;
break ;
}
}
}
else
{
FOR_EACH_MASK_FIELD ( * _mask , i , f )
{
if ( f - > dirty ( ) & & f - > active ( ) & & f - > field ( ) )
{
if ( id = = 0 )
id = f - > dlg ( ) ;
if ( f - > dirty ( ) > 1 ) // error on field content
{
id = f - > dlg ( ) ;
break ;
}
}
}
}
}
return id ;
}
bool TRelation_application : : save ( bool check_dirty )
{
static bool was_dirty = false ;
int pos = _mask - > id2pos ( DLG_SAVEREC ) ;
if ( pos < 0 | | ! _mask - > fld ( pos ) . active ( ) )
{
edit_cancel ( ) ;
return true ;
}
int err = NOERR ;
const int mode = _mask - > mode ( ) ;
if ( check_dirty )
{
const short dirty = mask_field_dirty ( ) ;
if ( mode = = MODE_QUERY )
{
const bool cont = ! dirty | | yesno_box ( TR ( " Annullare i dati inseriti? " ) ) ;
return cont ;
}
if ( ! dirty & & ! was_dirty )
{
edit_cancel ( ) ;
return true ;
}
const KEY last = _mask - > last_key ( ) ;
const bool annulla = last = = K_ESC | | last = = K_QUIT | | last = = K_F9 ;
const bool errore = dirty & & _mask - > field ( dirty ) . dirty ( ) > 1 ;
KEY k ;
if ( errore )
{
if ( annulla )
{
TString w ;
TMask_field & df = _mask - > field ( dirty ) ;
if ( df . is_edit ( ) )
w = ( ( TEdit_field & ) df ) . get_warning ( ) ;
if ( w . blank ( ) )
{
w = df . prompt ( ) ;
if ( ! w . blank ( ) )
{
w . trim ( ) ;
w < < ' ' < < TR ( " inconsistente. " ) ;
}
}
if ( w . blank ( ) )
w = TR ( " Campo inconsistente. " ) ;
w < < ' \n ' ;
switch ( last )
{
case K_ESC :
w < < TR ( " Si desidera annullare? " ) ; break ;
case K_QUIT :
w < < TR ( " Si desidera uscire? " ) ; break ;
default :
w < < TR ( " Si desidera continuare? " ) ; break ;
}
k = yesno_box ( w ) ? K_NO : K_ESC ;
if ( k = = K_ESC )
_mask - > first_focus ( - dirty ) ;
}
else k = K_ESC ;
}
else
k = yesnocancel_box ( TR ( " Si desidera registrare? " ) ) ;
if ( k = = K_ESC | | k = = K_NO )
{
edit_cancel ( ) ;
was_dirty = false ;
return k = = K_NO ;
}
if ( annulla )
{
TMask_field & ff = _mask - > focus_field ( ) ;
if ( ff . focusdirty ( ) & & ff . is_edit ( ) ) // I need simulate tab on the current field!
{
if ( ! ff . on_key ( K_TAB ) )
{
_mask - > first_focus ( - ff . dlg ( ) ) ;
was_dirty = true ;
return false ;
}
}
if ( ! _mask - > check_fields ( ) ) // Exit with ESC didn't check values
{
// check_fields sets the focus on the blocking field
_mask - > first_focus ( - _mask - > focus_field ( ) . dlg ( ) ) ;
was_dirty = true ;
return false ;
}
}
}
was_dirty = false ;
TWait_cursor hourglass ;
if ( mode = = MODE_INS )
{
bool changed = true ;
bool changed_key = false ;
while ( changed )
{
err = write ( * _mask ) ;
if ( err = = _isreinsert )
{
changed = autonum ( _mask , true ) ;
if ( ! changed )
{
_mask - > disable_starting_check ( ) ;
enable_query ( ) ; // Abilita chiave 1 per rinumerazione manuale
}
else
changed_key = true ;
}
else
changed = false ;
}
if ( err = = NOERR )
{
if ( changed_key )
message_box ( _renum_message ) ;
get_relation ( ) - > save_status ( ) ;
set_limits ( ) ;
get_relation ( ) - > restore_status ( ) ;
}
}
else
{
get_relation ( ) - > restore_status ( ) ;
err = rewrite ( * _mask ) ;
}
switch ( err )
{
case NOERR :
_recins = get_relation ( ) - > lfile ( ) . recno ( ) ;
mask2mail ( * _mask ) ;
break ;
case _isreinsert :
warning_box ( TR ( " Esiste gi<67> un elemento con la stessa chiave " ) ) ;
break ;
case _isnowarning :
break ;
default :
error_box ( FR ( " Impossibile registrare i dati: errore %d " ) , err ) ;
break ;
}
return err = = NOERR ;
}
int TRelation_application : : read ( TMask & m )
{
const TRelation & r = * get_relation ( ) ;
/* Metodo VECCHIO!
const int max = m . fields ( ) ;
for ( int i = 0 ; i < max ; i + + )
{
if ( m . fld ( i ) . is_sheet ( ) )
{
TSheet_field & f = ( TSheet_field & ) m . fld ( i ) ;
if ( f . record ( ) & & ! f . external_record ( ) )
f . record ( ) - > read ( * f . putkey ( r ) ) ;
}
}
*/
if ( m . sheets ( ) > 0 ) // Metodo Salvatempo
{
FOR_EACH_MASK_SHEET ( m , i , s )
{
if ( s - > record ( ) & & ! s - > external_record ( ) )
s - > record ( ) - > read ( * s - > putkey ( r ) ) ;
}
}
m . autoload ( r ) ;
return NOERR ;
}
int TRelation_application : : write ( const TMask & m )
{
TRelation & r = * get_relation ( ) ;
m . autosave ( r ) ;
r . curr ( ) . set_creation_info ( ) ;
// write relation and all independent sheets
int err = r . write ( ) ;
FOR_EACH_MASK_SHEET ( m , i , s )
{
if ( s - > record ( ) & & ! s - > external_record ( ) )
err | = s - > record ( ) - > write ( false ) ;
}
return err ;
}
int TRelation_application : : rewrite ( const TMask & m )
{
TRelation & r = * get_relation ( ) ;
m . autosave ( r ) ;
r . curr ( ) . set_modify_info ( ) ;
// rewrite relation and all independent sheets
r . rewrite ( ) ;
int err = r . status ( ) ;
FOR_EACH_MASK_SHEET ( m , i , s )
{
if ( s - > record ( ) & & ! s - > external_record ( ) )
err | = s - > record ( ) - > write ( true ) ;
}
return err ;
}
const char * TRelation_application : : record_description ( const TRelation & r ) const
{ return r . file ( ) . description ( ) ; }
// @doc INTERNAL
// @mfunc Cancella il record corrente
//
// @rdesc Ritorna se il record e' stato eliminato
bool TRelation_application : : relation_remove ( )
// @comm Se la maschera e' in MODE_MOD non e' possibile cancellare il record e viene
// emesso un <f CHECK> di errore.
{
CHECK ( _mask - > edit_mode ( ) , " You can call remove in edit mode only " ) ;
TRelation & r = * get_relation ( ) ;
r . restore_status ( ) ;
if ( protected_record ( r ) )
return warning_box ( FR ( " %s non eliminabile " ) , record_description ( r ) ) ;
if ( _curr_transaction = = TRANSACTION_DELETE | |
delete_box ( FR ( " Confermare eliminazione %s " ) , record_description ( r ) ) )
{
r . restore_status ( ) ;
const bool ok = remove ( ) ;
if ( ok | | is_transaction ( ) )
set_limits ( ) ;
else
{
const int err = r . status ( ) ;
if ( err ! = NOERR ) // Succede nei remove con richiesta di conferma all'utente
return error_box ( FR ( " Errore di cancellazione %d " ) , err ) ;
}
}
return TRUE ;
}
bool TRelation_application : : protected_record ( TRelation & r )
{
if ( user_can_delete ( & r ) )
return protected_record ( r . curr ( ) ) ;
return true ;
}
bool TRelation_application : : remove ( )
{
int err = get_relation ( ) - > remove ( ) ;
if ( err = = NOERR )
{
const int maxf = _mask - > fields ( ) ;
for ( int i = 0 ; i < maxf ; i + + )
{
const TMask_field & mf = _mask - > fld ( i ) ;
if ( mf . is_sheet ( ) )
{
TSheet_field & f = ( TSheet_field & ) mf ;
if ( f . record ( ) & & ! f . external_record ( ) )
err | = f . record ( ) - > remove ( ) ;
}
}
}
if ( err = = NOERR )
{
_mask - > set_mode ( NO_MODE ) ;
mask2mail ( * _mask ) ;
}
return err = = NOERR ;
}
bool TRelation_application : : firm_change_enabled ( ) const
{
bool ok = TApplication : : firm_change_enabled ( ) ;
ok & = ( _mask = = NULL | | _mask - > query_mode ( ) ) & & _lnflag = = 0 ;
return ok ;
}
void TRelation_application : : main_loop ( )
{
KEY k ;
do {
// ciclo delle transazioni
_recins = - 1 ;
// imposta la maschera in query mode
query_mode ( ) ;
_mask - > open_modal ( ) ;
// Provoca l'autopremimento per il messaggio di LINK
if ( _lnflag )
{
if ( _trans_counter < _ntransactions )
{
// la transazione <20> sul .ini : la imposta nelle variabili _curr_transaction...
if ( load_transaction ( ) )
{
// la transazione necessita di autopremimento
_autodelete = _curr_transaction = = TRANSACTION_DELETE ;
if ( _curr_transaction = = TRANSACTION_INSERT )
_mask - > send_key ( K_CTRL + ' N ' , 0 ) ;
else
_mask - > send_key ( K_AUTO_ENTER , 0 ) ;
}
}
else // la transazione non <20> sul .ini
{
_mask - > send_key ( K_AUTO_ENTER , 0 ) ;
}
}
if ( is_transaction ( ) )
ini2query_mask ( ) ;
do
{
const bool change = firm_change_enabled ( ) ;
// Dis/abilita cambio ditta
enable_menu_item ( M_FILE_NEW , change ) ;
if ( _mask - > edit_mode ( ) )
{
if ( _autodelete )
{
const int pos = _mask - > id2pos ( DLG_DELREC ) ;
if ( pos > = 0 & & _mask - > fld ( pos ) . active ( ) )
_mask - > send_key ( K_CTRL + ' E ' , 0 ) ;
else
error_box ( TR ( " Elemento non eliminabile. " ) ) ;
_autodelete = FALSE ;
}
}
if ( _curr_trans_mode = = TM_BATCH )
{
batch ( ) ;
k = _mask - > check_mask ( ) ;
batch ( false ) ;
}
else
k = _mask - > run ( ) ;
switch ( k )
{
case K_ESC :
if ( save ( TRUE ) )
{
if ( save_and_quit ( ) )
k = K_QUIT ;
else
{
edit_cancel ( ) ; // Novit<69> 19-06-2012
query_mode ( ) ;
}
}
break ;
case K_QUIT :
if ( ! save ( TRUE ) )
k = K_ENTER ;
break ;
case K_F1 :
dispatch_e_menu ( M_HELP_CONTENTS ) ;
break ;
case K_F2 :
dispatch_e_menu ( M_FILE_ABOUT ) ;
break ;
case K_ENTER :
if ( _lnflag & & _curr_transaction ! = TRANSACTION_RUN )
{
if ( find ( 1 ) )
{
if ( _curr_transaction = = TRANSACTION_INSERT )
_curr_transaction = TRANSACTION_MODIFY ;
if ( ! modify_mode ( ) )
k = K_QUIT ;
}
else
{
if ( _curr_transaction = = TRANSACTION_MODIFY )
_curr_transaction = TRANSACTION_INSERT ;
insert_mode ( ) ;
}
}
else
{
if ( find ( 0 ) )
modify_mode ( ) ;
else
insert_mode ( ) ;
}
if ( _curr_trans_mode = = TM_AUTOMATIC | | _curr_trans_mode = = TM_BATCH )
_mask - > send_key ( K_CTRL + ' R ' , 0 ) ;
break ;
case K_SAVE :
if ( save ( FALSE ) )
{
if ( save_and_quit ( ) )
{
k = K_QUIT ;
}
else
{
if ( save_and_new ( ) & & can_I_write ( NULL ) )
{
if ( _mask - > insert_mode ( ) )
insert_mode ( ) ;
else
query_mode ( ) ;
}
else
{
const TMask_field & f = _mask - > focus_field ( ) ;
_mask - > first_focus ( - f . dlg ( ) , false ) ;
modify_mode ( ) ;
}
}
}
break ;
case K_INS :
if ( _mask - > query_mode ( ) | | save ( TRUE ) )
{
const bool trovato = _mask - > query_mode ( ) & & test_key ( 1 , FALSE ) & & find ( 1 ) ;
if ( trovato )
{
if ( is_transaction ( ) )
_curr_transaction = TRANSACTION_MODIFY ;
else
warning_box ( TR ( " Elemento gia' presente " ) ) ;
modify_mode ( ) ;
}
else
insert_mode ( ) ;
}
if ( _curr_trans_mode = = TM_AUTOMATIC | | _curr_trans_mode = = TM_BATCH )
_mask - > send_key ( K_CTRL + ' R ' , 0 ) ;
break ;
case K_DEL :
if ( _mask - > query_mode ( ) )
{
delete_mode ( ) ;
}
else
{
if ( relation_remove ( ) )
{
query_mode ( ) ;
if ( _autoins_caller . not_empty ( ) | | is_transaction ( ) )
{
if ( _lnflag ) _recins = 0 ;
k = K_QUIT ;
}
}
}
break ;
case K_F9 :
if ( _mask - > query_mode ( ) | | save ( TRUE ) )
search_mode ( ) ;
break ;
default :
if ( save ( TRUE ) )
{
setkey ( ) ;
int err = ~ NOERR ;
switch ( k )
{
case K_HOME :
err = file ( ) . readat ( _first , _testandlock ) ;
break ;
case K_NEXT :
{
TCursor * c = get_filtered_cursor ( ) ;
if ( ! has_filtered_cursor ( ) | | c - > curr ( ) . num ( ) ! = file ( ) . curr ( ) . num ( ) )
{
for ( TEdit_field * e = ( TEdit_field * ) _mask - > get_key_field ( 1 , TRUE ) ; e ; e = ( TEdit_field * ) _mask - > get_key_field ( 1 , FALSE ) )
{
if ( e - > is_kind_of ( CLASS_EDIT_FIELD ) & & e - > shown ( ) & & e - > browse ( ) ! = NULL ) // Ignora campi invisibili o senza check
{
TCursor * b = e - > browse ( ) - > cursor ( ) ;
if ( b & & b - > curr ( ) . num ( ) = = file ( ) . curr ( ) . num ( ) )
{
c = b ;
break ;
}
}
}
}
TCursor * cur = c ;
if ( c = = NULL )
cur = new TCursor ( get_relation ( ) ) ;
err = file ( ) . reread ( ) ;
cur - > curr ( ) = file ( ) . curr ( ) ;
cur - > read ( ) ;
+ + ( * cur ) ;
while ( cur - > pos ( ) < cur - > items ( ) & & ! can_I_read ( cur - > relation ( ) ) )
+ + ( * cur ) ;
file ( ) . curr ( ) = cur - > curr ( ) ;
if ( can_I_read ( cur - > relation ( ) ) )
err = get_relation ( ) - > read ( _isequal , _testandlock ) ;
if ( c = = NULL )
delete cur ;
}
break ;
case K_PREV :
{
TCursor * c = get_filtered_cursor ( ) ;
if ( ! has_filtered_cursor ( ) | | c - > curr ( ) . num ( ) ! = file ( ) . curr ( ) . num ( ) )
{
for ( TEdit_field * e = ( TEdit_field * ) _mask - > get_key_field ( 1 , TRUE ) ; e ; e = ( TEdit_field * ) _mask - > get_key_field ( 1 , FALSE ) )
{
if ( e - > is_kind_of ( CLASS_EDIT_FIELD ) & & e - > shown ( ) & & e - > browse ( ) ! = NULL ) // Ignora campi invisibili o senza check
{
TCursor * b = e - > browse ( ) - > cursor ( ) ;
if ( b & & b - > curr ( ) . num ( ) = = file ( ) . curr ( ) . num ( ) )
{
c = b ;
break ;
}
}
}
}
TCursor * cur = c ;
if ( c = = NULL )
cur = new TCursor ( get_relation ( ) ) ;
file ( ) . reread ( ) ;
cur - > curr ( ) = file ( ) . curr ( ) ;
cur - > read ( ) ;
- - ( * cur ) ;
while ( cur - > pos ( ) > 0 & & ! can_I_read ( cur - > relation ( ) ) )
- - ( * cur ) ;
file ( ) . curr ( ) = cur - > curr ( ) ;
if ( can_I_read ( cur - > relation ( ) ) )
err = get_relation ( ) - > read ( _isequal , _testandlock ) ;
if ( c = = NULL )
delete cur ;
}
break ;
case K_END :
err = file ( ) . readat ( _last , _testandlock ) ;
break ;
default :
break ;
}
if ( err = = NOERR | | err = = _islocked )
{
_navigating = true ;
modify_mode ( ) ;
_navigating = false ;
}
else
query_mode ( ) ;
}
break ;
}
} while ( k ! = K_QUIT ) ;
if ( _mask - > is_open ( ) )
_mask - > close_modal ( ) ;
_mask - > set_mode ( NO_MODE ) ;
if ( autoins_caller ( ) . not_empty ( ) & & _recins > = 0 )
{
NFCHECK ( " Obsolete LINK message calling convention " ) ;
TString16 num ;
num . format ( " %ld " , _recins ) ;
TMessage msg ( autoins_caller ( ) , _lnflag ? MSG_LN : MSG_AI , num ) ;
msg . send ( ) ;
}
if ( is_transaction ( ) )
{
TConfig ini ( _trans_ini . row ( _trans_counter ) , " Transaction " ) ;
ini . set ( " Record " , _recins ) ;
if ( _recins > = 0 )
{
ini . set ( " Result " , " OK " ) ;
ini . set ( " Error " , " 0 " ) ;
edit_mask2ini ( ) ;
}
else
{
const int err = get_relation ( ) - > status ( ) ;
ini . set ( " Result " , err = = NOERR ? " CANCEL " : " ERROR " ) ;
ini . set ( " Error " , err ) ;
}
if ( _curr_trans_mode = = TM_BATCH )
{
TString_array & errs = errors ( ) ;
FOR_EACH_ARRAY_ROW ( errs , r , s )
ini . set ( " ErrMsg " , * s , " Main " , false , r ) ;
TString_array & warns = warnings ( ) ;
FOR_EACH_ARRAY_ROW ( warns , r1 , s1 )
ini . set ( " WarningMsg " , * s1 , " Main " , false , r1 ) ;
}
}
_trans_counter + + ;
} while ( _trans_counter < _ntransactions ) ;
}
bool TRelation_application : : filter ( )
{
if ( parse_command_line ( ) )
return true ;
TMailbox mail ;
TMessage * msg = mail . next_s ( MSG_FS ) ;
if ( msg )
{
_mask = get_mask ( MODE_MOD ) ;
TToken_string body ( msg - > body ( ) ) ;
short id = body . get_int ( ) ;
while ( id > 0 )
{
_search_id = id ;
TEdit_field & f = _mask - > efield ( id ) ;
TCursor * cur = f . browse ( ) - > cursor ( ) ;
TRectype & rec = cur - > curr ( ) ;
rec . zero ( ) ;
TString80 t ;
const char * s ;
while ( ( s = body . get ( ) ) ! = NULL )
{
t = s ;
const int u = t . find ( ' = ' ) ;
if ( u < 0 )
{
id = atoi ( t ) ;
break ;
}
_fixed . add ( t ) ;
const short fid = atoi ( t . left ( u ) ) ;
const TFieldref * campo = _mask - > field ( fid ) . field ( ) ;
if ( campo ! = NULL )
campo - > write ( t . mid ( u + 1 ) , rec ) ;
}
cur - > setfilter ( " " ) ;
cur - > setregion ( rec , rec , 0x2 ) ;
if ( s = = NULL ) id = 0 ;
}
}
mail . restart ( ) ;
msg = mail . next_s ( MSG_AI ) ;
if ( msg ) _autoins_caller = msg - > from ( ) ;
mail . restart ( ) ;
msg = mail . next_s ( MSG_LN ) ;
if ( msg )
{
TToken_string body ( msg - > body ( ) ) ;
const int key = body . get_int ( ) ;
_autoins_caller = msg - > from ( ) ;
_lnflag = TRUE ;
TString str , tmp ;
const char * v = body . get ( ) ;
for ( int i = 0 ; v ! = NULL & & i < _mask - > fields ( ) ; i + + )
{
TMask_field & f = _mask - > fld ( i ) ;
if ( f . active ( ) & & f . dlg ( ) > 0 & & f . in_key ( key ) )
{
str = v ;
tmp . format ( " %d= " , f . dlg ( ) ) ;
str . insert ( tmp , 0 ) ;
_fixed . add ( str ) ;
v = body . get ( ) ;
}
}
}
mail . restart ( ) ;
msg = mail . next_s ( MSG_ED ) ;
if ( msg )
{
TToken_string body ( msg - > body ( ) ) ;
const int key = body . get_int ( ) ;
_autoins_caller = msg - > from ( ) ;
_lnflag = 2 ;
TAssoc_array field_values ;
const char * s ;
TString t , v ;
while ( ( s = body . get ( ) ) ! = NULL )
{
t = s ;
const int u = t . find ( ' = ' ) ;
CHECKS ( u > 0 , " Invalid edit message " , ( const char * ) body ) ;
if ( u > 0 )
{
v = t . mid ( u + 1 ) ;
t . cut ( u ) ;
field_values . add ( t , v ) ;
}
}
for ( int i = 0 ; i < _mask - > fields ( ) ; i + + )
{
TMask_field & f = _mask - > fld ( i ) ;
const TFieldref * field = f . field ( ) ;
if ( field & & f . in_key ( key ) )
{
TString16 field_name ( field - > name ( ) ) ;
const int from = field - > from ( ) ;
const int to = field - > to ( ) ;
if ( to > = 0 )
field_name < < " [ " < < ( from + 1 ) ;
const TString * v = ( const TString * ) field_values . objptr ( field_name ) ;
TString val ;
if ( v = = NULL & & to > = 0 )
{
v = ( const TString * ) field_values . objptr ( field - > name ( ) ) ;
if ( v )
val = v - > sub ( from , to ) ;
}
else
if ( v ) val = * v ;
if ( v & & f . dlg ( ) > 0 )
{
t . format ( " %d= " , f . dlg ( ) ) ;
val . insert ( t , 0 ) ;
_fixed . add ( val ) ;
}
}
}
}
return TRUE ;
}
void TRelation_application : : set_link ( TMask & m , const char * keyexpr )
{
CHECK ( keyexpr ! = NULL , " Invalid expression " ) ;
TToken_string body ( keyexpr ) ;
const int key = body . get_int ( ) ;
_lnflag = TRUE ;
const char * v = body . get ( ) ;
TString16 tmp ;
const int max = m . fields ( ) ;
for ( int i = 0 ; i < max & & v ! = NULL ; i + + )
{
TMask_field & f = m . fld ( i ) ;
if ( f . active ( ) & & f . dlg ( ) > 0 & & f . in_key ( key ) )
{
TString s ( v ) ;
tmp . format ( " %d= " , f . dlg ( ) ) ;
s . insert ( tmp , 0 ) ;
_fixed . add ( s ) ;
v = body . get ( ) ;
}
}
}
bool TRelation_application : : parse_command_line ( )
{
_trans_ini . destroy ( ) ;
_trans_counter = 0 ;
_curr_transaction = " " ;
_curr_trans_mode = ' I ' ;
TFilename ini ;
for ( int i = argc ( ) - 1 ; i > 0 ; i - - )
{
ini = argv ( i ) ;
if ( ( ini [ 0 ] = = ' - ' | | ini [ 0 ] = = ' / ' ) & & ( ini [ 1 ] = = ' I ' | | ini [ 1 ] = = ' i ' ) )
{
ini . ltrim ( 2 ) ;
if ( ini . starts_with ( " = " ) )
ini . ltrim ( 1 ) ;
CHECK ( ! ini . blank ( ) , " Manca l'indicazione della transazione. Il nome va indicato di seguito al -i, senza interporre spaziatura. " ) ;
if ( ini . find ( ' * ' ) > = 0 )
{
// metachars:
list_files ( ini , _trans_ini ) ;
}
else
{
if ( ini . exist ( ) )
_trans_ini . add ( ini ) ;
else
cantread_box ( ini ) ;
}
break ;
}
}
_ntransactions = _trans_ini . items ( ) ;
_lnflag = _ntransactions > 0 ;
return _lnflag ! = 0 ;
}
// il valore di ritorno indica se attivare l'"automagia":
// spedizione dei tasti e precaricamento della maschera
bool TRelation_application : : load_transaction ( )
{
bool retv = FALSE ;
if ( _trans_counter < _ntransactions )
{
TConfig cnf ( _trans_ini . row ( _trans_counter ) , " Transaction " ) ;
_curr_transaction = cnf . get ( " Action " ) ;
_curr_transaction . upper ( ) ;
_curr_trans_mode = toupper ( cnf . get ( " Mode " ) [ 0 ] ) ;
_curr_trans_from = cnf . get ( " From " ) ;
const long firm = cnf . get_long ( " Firm " ) ;
if ( firm > 0 )
{
bool ok = set_firm ( firm ) ;
if ( ok )
_mask - > on_firm_change ( ) ;
else
error_box ( FR ( " La ditta %ld non esiste " ) , firm ) ;
}
if ( _curr_transaction = = TRANSACTION_RUN )
retv = false ; // Ho gia' finito qui: basta il cambio ditta
else
retv = true ; // Attiva automagia
}
return retv ;
}
void TRelation_application : : on_firm_change ( )
{
TApplication : : on_firm_change ( ) ;
if ( _mask ! = NULL )
{
set_limits ( 0x3 ) ;
}
}
void TRelation_application : : ini2query_mask ( )
{
if ( is_transaction ( ) )
{
TString8 n ; n . format ( " %d " , get_relation ( ) - > lfile ( ) . num ( ) ) ;
TConfig ini ( _trans_ini . row ( _trans_counter ) , n ) ;
ini2mask ( ini , * _mask , TRUE ) ;
}
}
void TRelation_application : : ini2insert_mask ( )
{
if ( is_transaction ( ) )
{
TString8 n ; n . format ( " %d " , get_relation ( ) - > lfile ( ) . num ( ) ) ;
TConfig ini ( _trans_ini . row ( _trans_counter ) , n ) ;
ini2mask ( ini , * _mask , FALSE ) ;
}
}
void TRelation_application : : ini2mask ( TConfig & ini , TMask & m , bool query )
{
const TString16 defpar = ini . get_paragraph ( ) ;
TString tmp ;
_fixed . cut ( 0 ) ;
for ( int f = m . fields ( ) - 1 ; f > = 0 ; f - - )
{
TMask_field & campo = m . fld ( f ) ;
const TFieldref * fref = campo . field ( ) ;
if ( fref )
{
if ( ! query | | campo . in_key ( 0 ) )
{
const TString & str = fref - > read ( ini , defpar ) ;
if ( str . not_empty ( ) )
{
campo . set ( str ) ;
if ( query )
{
tmp . format ( " %d=%s " , campo . dlg ( ) , ( const char * ) str ) ;
_fixed . add ( tmp ) ;
}
}
}
}
else
{
if ( ! query & & campo . is_sheet ( ) )
{
TSheet_field & sheet = ( TSheet_field & ) campo ;
ini2sheet ( ini , sheet ) ;
}
}
}
ini . set_paragraph ( defpar ) ;
if ( query )
set_fixed ( ) ;
}
void TRelation_application : : edit_mask2ini ( )
{
const TString & str = _trans_ini . row ( _trans_counter ) ;
if ( str . full ( ) )
{
TString8 head ; head . format ( " %d " , get_relation ( ) - > lfile ( ) . num ( ) ) ;
TConfig ini ( str , head ) ;
mask2ini ( * _mask , ini ) ;
}
}
void TRelation_application : : ini2sheet ( TConfig & ini , TSheet_field & sheet )
{
if ( sheet . record ( ) ! = NULL )
{
const int lognum = sheet . record ( ) - > logic_num ( ) ;
const TMask & sm = sheet . sheet_mask ( ) ;
// scrive le righe nello sheet associato
TString16 defpar ;
for ( int r = 1 ; ; r + + )
{
defpar . format ( " %d,%d " , lognum , r ) ;
if ( ini . set_paragraph ( defpar ) )
{
TToken_string & row = sheet . row ( r - 1 ) ;
for ( int sf = sm . fields ( ) - 1 ; sf > = 0 ; sf - - )
{
TMask_field & campo = sm . fld ( sf ) ;
const TFieldref * fref = campo . field ( ) ;
if ( fref )
{
const TString & str = fref - > read ( ini , defpar ) ;
row . add ( str , sheet . cid2index ( campo . dlg ( ) ) ) ;
}
}
sheet . check_row ( r - 1 ) ;
}
else
break ;
}
}
}
void TRelation_application : : sheet2ini ( TSheet_field & sheet , TConfig & ini )
{
if ( sheet . record ( ) ! = NULL )
{
const int lognum = sheet . record ( ) - > logic_num ( ) ;
const TMask & sm = sheet . sheet_mask ( ) ;
// scrive le righe degli sheet associati
TString16 defpar ;
TString str ;
int r ;
for ( r = 1 ; r < = sheet . items ( ) ; r + + )
{
defpar . format ( " %d,%d " , lognum , r ) ;
TMask_field * fkey ;
sheet . restart_key ( ) ;
while ( ( fkey = sheet . get_key ( str ) ) )
{
ini . set ( str , fkey - > get ( ) , defpar ) ;
}
TToken_string & row = sheet . row ( r - 1 ) ;
const char * value ;
int i ;
for ( i = 0 , value = row . get ( 0 ) ; value ; i + + , value = row . get ( ) )
{
const TMask_field & campo = sm . field ( FIRST_FIELD + i ) ;
const TFieldref * fr = campo . field ( ) ;
if ( fr )
{
if ( value = = NULL | | * value = = ' \0 ' )
value = " " ;
// ini.set(fr->name(), value, defpar);
fr - > write ( ini , defpar , value ) ;
}
}
}
for ( r = sheet . items ( ) + 1 ; ; r + + )
{
defpar . format ( " %d,%d " , lognum , r ) ;
if ( ini . set_paragraph ( defpar ) )
ini . remove_all ( ) ;
else
break ;
}
}
}
void TRelation_application : : mask2ini ( const TMask & m , TConfig & ini )
{
ini . set ( " Firm " , get_firm ( ) , " Transaction " ) ;
ini . set ( " User " , user ( ) ) ;
ini . set ( " HostName " , get_hostname ( ) ) ;
int year , release , tag , patch ;
if ( get_version_info ( year , release , tag , patch ) )
{
TString80 ver ;
ver . format ( " %d %d.%d-%d " , year , release , tag , patch ) ;
ini . set ( " Version " , ver ) ;
}
const TLocalisamfile & lfile = get_relation ( ) - > lfile ( ) ;
TString16 defpar ;
defpar . format ( " %d " , lfile . num ( ) ) ;
ini . set_paragraph ( defpar ) ;
switch ( lfile . num ( ) )
{
case LF_TAB :
case LF_TABCOM :
case LF_TABGEN :
{
const TString & tabname = lfile . curr ( ) . get ( " COD " ) ;
ini . set ( " COD " , tabname , defpar ) ;
}
break ;
}
for ( int f = 0 ; f < m . fields ( ) ; f + + )
{
TMask_field & campo = m . fld ( f ) ;
if ( campo . shown ( ) )
{
const TFieldref * fr = campo . field ( ) ;
if ( fr )
{
if ( campo . empty ( ) )
fr - > write ( ini , defpar , " " ) ;
else
{
if ( campo . class_id ( ) = = CLASS_DATE_FIELD & & campo . right_justified ( ) )
{
const TDate d ( campo . get ( ) ) ;
fr - > write ( ini , defpar , d . string ( ANSI ) ) ;
}
else
fr - > write ( ini , defpar , campo . get ( ) ) ;
}
}
else
if ( campo . is_sheet ( ) )
{
TSheet_field & sheet = ( TSheet_field & ) campo ;
sheet2ini ( sheet , ini ) ; // It's virtual
}
}
}
ini . set_paragraph ( defpar ) ; // Reimposta paragrafo standard
}
bool TRelation_application : : mask2mail ( const TMask & m )
{
TWait_cursor hourglass ;
bool ok = _curr_trans_from . empty ( ) & & : : can_dispatch_transaction ( get_relation ( ) - > curr ( ) ) ;
if ( ok )
{
TFilename ininame ; ininame . temp ( " msg " , " ini " ) ;
if ( ok ) // Test qualunque per usare {}
{
TConfig ini ( ininame , " Transaction " ) ;
const char * action = " " ;
char mode [ 2 ] = { TM_AUTOMATIC , ' \0 ' } ;
switch ( m . mode ( ) )
{
case NO_MODE :
action = TRANSACTION_DELETE ;
break ;
case MODE_MOD :
action = TRANSACTION_MODIFY ;
break ;
default :
action = TRANSACTION_INSERT ;
break ;
}
ini . set ( " Action " , action ) ;
ini . set ( " Mode " , mode ) ;
mask2ini ( m , ini ) ;
}
ok = : : dispatch_transaction ( get_relation ( ) - > curr ( ) , ininame ) ;
xvt_fsys_remove_file ( ininame ) ;
}
return ok ;
}