git-svn-id: svn://10.65.10.50/branches/R_10_00@22933 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			2685 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2685 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <xinclude.h>
 | 
						||
 | 
						||
#include "cg3.h"
 | 
						||
#include "cglib02.h"
 | 
						||
#include "cg3600.h"
 | 
						||
 | 
						||
#include <applicat.h>
 | 
						||
#include <colmask.h>
 | 
						||
#include <controls.h>
 | 
						||
#include <dongle.h>
 | 
						||
#include <execp.h>
 | 
						||
#include <progind.h>
 | 
						||
#include <relation.h>
 | 
						||
#include <recset.h>
 | 
						||
#include <urldefid.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include <clifo.h>
 | 
						||
#include <causali.h>
 | 
						||
#include <mov.h>
 | 
						||
#include <pconti.h>
 | 
						||
#include <rmov.h>
 | 
						||
#include <saldi.h>
 | 
						||
 | 
						||
#include "../ca/movana.h"
 | 
						||
#include "../ca/rmovana.h"
 | 
						||
 | 
						||
class TGrid_mask;
 | 
						||
 | 
						||
class TQuery_mask : public TAutomask
 | 
						||
{ 
 | 
						||
  TGrid_mask* _gm;
 | 
						||
	TString4 _last_tipo;
 | 
						||
 | 
						||
protected:    
 | 
						||
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | 
						||
 | 
						||
public:
 | 
						||
  void do_query();
 | 
						||
 | 
						||
  TQuery_mask(TGrid_mask* gm);
 | 
						||
  virtual ~TQuery_mask() { }
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
class TMastrini_video : public TSkeleton_application
 | 
						||
{
 | 
						||
  TQuery_mask* _qm;
 | 
						||
  TGrid_mask* _gm;
 | 
						||
  
 | 
						||
protected:
 | 
						||
  virtual bool create();
 | 
						||
  virtual void main_loop();
 | 
						||
  virtual bool destroy();
 | 
						||
 | 
						||
public:
 | 
						||
  TQuery_mask & query_mask() { return *_qm; }
 | 
						||
 | 
						||
};
 | 
						||
HIDDEN inline TMastrini_video& app()
 | 
						||
{ return (TMastrini_video&)main_app();}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TList
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TList : public TContainer
 | 
						||
{           
 | 
						||
  TArray _data;
 | 
						||
 | 
						||
protected:
 | 
						||
  // @cmember Ritorna un puntatore al primo oggetto del contenitore
 | 
						||
  virtual TObject* first_item( ) { return _data.first_item(); }
 | 
						||
  // @cmember Ritorna un puntatore all'ultimo oggetto del contenitore
 | 
						||
  virtual TObject* last_item( ) { return _data.last_item(); }
 | 
						||
  // @cmember Ritorna un puntatore all'oggetto successivo all'oggetto corrente
 | 
						||
  virtual TObject* succ_item( ) { return _data.succ_item(); }
 | 
						||
  // @cmember Ritorna un puntatore all'oggetto che precede l'oggetto corrente
 | 
						||
  virtual TObject* pred_item( ) { return _data.pred_item(); }
 | 
						||
  // @cmember Ritorna il numero di oggetti nel contenitore
 | 
						||
  virtual long objects( ) const { return _data.objects(); }
 | 
						||
 | 
						||
public:
 | 
						||
  long items() const { return _data.items(); }
 | 
						||
  void destroy() { _data.destroy(); }
 | 
						||
  long insert(TObject* obj, long pos) { return _data.insert(obj, pos); }
 | 
						||
  long append(TObject* obj, long pos = -1);
 | 
						||
  bool remove(long pos) { _data.remove(pos, true); return true; }
 | 
						||
 | 
						||
  const TObject& obj(long index) const
 | 
						||
  { const TObject* o = _data.objptr(index); CHECK(o, "Null list item"); return *o; }
 | 
						||
};
 | 
						||
 | 
						||
long TList::append(TObject* obj, long index)
 | 
						||
{
 | 
						||
  if (index < 0 || index >= items()) 
 | 
						||
    index = items();
 | 
						||
  else
 | 
						||
    index++;
 | 
						||
  return insert(obj, index);  
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TMastrino
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
enum tipo_riga_mastrino { riga_mastrino, riga_contropartita };
 | 
						||
 | 
						||
class TRiga_mastrino : public TObject
 | 
						||
{            
 | 
						||
  tipo_riga_mastrino _type; // Tipo della riga
 | 
						||
  TRecnotype _mov, _rmov;   // Numero fisico di record movimento e riga movimento
 | 
						||
  real _dare, _avere;       // Progressivi dare ed avere
 | 
						||
  TDate _data;              // Data di registrazione (Ottimizzazione)
 | 
						||
  
 | 
						||
public:  
 | 
						||
  tipo_riga_mastrino tipo() const { return _type; }
 | 
						||
  TRecnotype rmov() const { return _rmov; }
 | 
						||
  TRecnotype mov() const { return _mov; }
 | 
						||
  
 | 
						||
  const TDate& data() const { return _data; }  
 | 
						||
  const real& dare() const { return _dare; }
 | 
						||
  const real& avere() const { return _avere; }
 | 
						||
  TImporto saldo() const;           // Dare-Avere normalizzato
 | 
						||
  
 | 
						||
  TRiga_mastrino(tipo_riga_mastrino trig, 
 | 
						||
                 TRecnotype rmov, TRecnotype mov,
 | 
						||
                 const real& d, const real& a,
 | 
						||
                 const TDate& datareg);
 | 
						||
  virtual ~TRiga_mastrino() { }
 | 
						||
};
 | 
						||
 | 
						||
TRiga_mastrino::TRiga_mastrino(tipo_riga_mastrino trig, 
 | 
						||
                               TRecnotype rmov, TRecnotype mov,
 | 
						||
                               const real& d, const real& a,
 | 
						||
                               const TDate& datareg)
 | 
						||
              : _type(trig), _rmov(rmov), _mov(mov), 
 | 
						||
                _dare(d), _avere(a), _data(datareg) 
 | 
						||
{ }
 | 
						||
 | 
						||
TImporto TRiga_mastrino::saldo() const
 | 
						||
{
 | 
						||
  TImporto imp('D', _dare - _avere);
 | 
						||
  imp.normalize();            
 | 
						||
  return imp;
 | 
						||
}  
 | 
						||
 | 
						||
class TMastrino : public TObject
 | 
						||
{  
 | 
						||
  static long _instances;
 | 
						||
  static TCursor* _cur;
 | 
						||
  static TRelation* _rel;
 | 
						||
  static TLocalisamfile *_rmov;   // File principale della relazione
 | 
						||
  static TLocalisamfile *_mov;    // File secondario della relazione
 | 
						||
  
 | 
						||
  TBill _conto;                   // Conto del mastrino
 | 
						||
  int _esercizio;                 // Esercizio di riferimento (eventualmente 0)
 | 
						||
  TDate _da_data, _a_data;        // Date limite
 | 
						||
  TString _da_caus, _a_caus;      // Causali limite
 | 
						||
  bool _provvis;                  // Includi provvisori                  
 | 
						||
  
 | 
						||
  real _pdare_ini, _pavere_ini;
 | 
						||
  real _pdare_per, _pavere_per;
 | 
						||
  real _pdare_fin, _pavere_fin;
 | 
						||
 | 
						||
  TList _riga;                    // Righe del mastrino
 | 
						||
 | 
						||
protected:
 | 
						||
  TCursor& cur() { return *_cur; }
 | 
						||
  TRelation& rel() { return *_rel; }
 | 
						||
  TLocalisamfile& rmov() { return *_rmov; }
 | 
						||
  TLocalisamfile& mov() { return *_mov; }
 | 
						||
  
 | 
						||
  void position_rel(long n);
 | 
						||
  TRiga_mastrino& row(long n) const { return (TRiga_mastrino&)_riga.obj(n); }
 | 
						||
 
 | 
						||
public:
 | 
						||
  long items() const { return _riga.items(); }
 | 
						||
 | 
						||
  void read(const TBill& conto, 
 | 
						||
            int annoes, const TDate& dd, const TDate& ad,
 | 
						||
            const TString& dc, const TString& ac, bool provvis);
 | 
						||
  void reread();
 | 
						||
  
 | 
						||
  TRiga_mastrino& operator[](long n) const { return row(n); }
 | 
						||
  const TRectype& riga(long n);
 | 
						||
  const TRectype& testata(long n);
 | 
						||
  
 | 
						||
  long first(tipo_riga_mastrino tipo = riga_mastrino) const; 
 | 
						||
  long pred(long rec, tipo_riga_mastrino tipo = riga_mastrino) const;
 | 
						||
  long succ(long rec, tipo_riga_mastrino tipo = riga_mastrino) const;
 | 
						||
  long last(tipo_riga_mastrino tipo = riga_mastrino) const;
 | 
						||
  
 | 
						||
  void destroy() { _riga.destroy(); }
 | 
						||
  
 | 
						||
  const real& progressivo_dare_iniziale() const { return _pdare_ini; }
 | 
						||
  const real& progressivo_avere_iniziale() const { return _pavere_ini; }
 | 
						||
  TImporto saldo_iniziale() const; 
 | 
						||
 | 
						||
  const real& progressivo_dare_finale() const { return _pdare_fin; }
 | 
						||
  const real& progressivo_avere_finale() const { return _pavere_fin; }
 | 
						||
  TImporto saldo_finale() const;
 | 
						||
  
 | 
						||
  real progressivo_dare_periodo() const { return _pdare_ini + _pdare_per; }
 | 
						||
  real progressivo_avere_periodo() const { return _pavere_ini + _pavere_per; }
 | 
						||
  TImporto saldo_periodo() const;
 | 
						||
  
 | 
						||
  const TBill& conto() const { return _conto; }
 | 
						||
  int esercizio() const { return _esercizio; }
 | 
						||
  const TDate& inizio_periodo() const { return _da_data; }
 | 
						||
  const TDate& fine_periodo() const { return _a_data; }
 | 
						||
  void periodo(TDate& dd, TDate& ad) const { dd = _da_data; ad = _a_data; }
 | 
						||
  
 | 
						||
  bool expandable(long rec) const;
 | 
						||
  bool expand(long rec);
 | 
						||
  bool collapse(long rec);
 | 
						||
 | 
						||
  TMastrino();
 | 
						||
  virtual ~TMastrino();
 | 
						||
};
 | 
						||
 | 
						||
long TMastrino::_instances = 0L;
 | 
						||
TCursor* TMastrino::_cur = NULL;
 | 
						||
TRelation* TMastrino::_rel = NULL;
 | 
						||
TLocalisamfile* TMastrino::_rmov = NULL;   // File principale della relazione
 | 
						||
TLocalisamfile* TMastrino::_mov = NULL;    // File secondario della relazione
 | 
						||
 | 
						||
TMastrino::TMastrino() : _esercizio(0)
 | 
						||
{          
 | 
						||
  if (_instances == 0L)
 | 
						||
  {            
 | 
						||
    _rel = new TRelation(LF_RMOV);
 | 
						||
    _rel->add(LF_MOV, "NUMREG==NUMREG");
 | 
						||
    _rmov = &_rel->lfile();
 | 
						||
    _mov = &_rel->lfile(LF_MOV);
 | 
						||
  }
 | 
						||
  _instances++;  
 | 
						||
}
 | 
						||
 | 
						||
TMastrino::~TMastrino()
 | 
						||
{
 | 
						||
  _instances--;  
 | 
						||
  if (_instances == 0L)
 | 
						||
  { 
 | 
						||
    delete _cur; _cur = NULL;
 | 
						||
    delete _rel; _rel = NULL;
 | 
						||
    _rmov = _mov = NULL;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
long TMastrino::succ(long rec, tipo_riga_mastrino tipo) const
 | 
						||
{ 
 | 
						||
  if (rec < 0)
 | 
						||
		rec = -1;
 | 
						||
  
 | 
						||
  const long ul = items();
 | 
						||
	long i;
 | 
						||
 | 
						||
  for (i = rec+1; i < ul; i++)
 | 
						||
  {
 | 
						||
    if (row(i).tipo() == tipo)
 | 
						||
      break;
 | 
						||
  }    
 | 
						||
  return i;
 | 
						||
}
 | 
						||
 | 
						||
long TMastrino::pred(long rec, tipo_riga_mastrino tipo) const
 | 
						||
{
 | 
						||
  if (rec > items()) rec = items();
 | 
						||
  long i;
 | 
						||
  for (i = rec-1; i >= 0; i--)
 | 
						||
  {
 | 
						||
    if (row(i).tipo() == tipo)
 | 
						||
      break;
 | 
						||
  }    
 | 
						||
  return i;
 | 
						||
}
 | 
						||
 | 
						||
long TMastrino::first(tipo_riga_mastrino tipo) const
 | 
						||
{ 
 | 
						||
  return succ(-1, tipo);
 | 
						||
}  
 | 
						||
 | 
						||
long TMastrino::last(tipo_riga_mastrino tipo) const
 | 
						||
{ 
 | 
						||
  return pred(items(), tipo);
 | 
						||
}  
 | 
						||
 | 
						||
void TMastrino::read(const TBill& conto, 
 | 
						||
                     int ae, const TDate& dd, const TDate& ad,
 | 
						||
                     const TString& dc, const TString& ac,
 | 
						||
                     bool provvis)
 | 
						||
{
 | 
						||
  TEsercizi_contabili esercizi;
 | 
						||
 | 
						||
  _conto = conto; 
 | 
						||
  _esercizio = ae;
 | 
						||
  
 | 
						||
  _riga.destroy();
 | 
						||
  
 | 
						||
  rmov().setkey(2);
 | 
						||
  TRectype& rmov_rec = rmov().curr(); 
 | 
						||
  TRectype& mov_rec  = mov().curr(); 
 | 
						||
 | 
						||
  if (ae <= 0)
 | 
						||
  {
 | 
						||
    if (dd.ok()) 
 | 
						||
      ae = esercizi.date2esc(dd);
 | 
						||
    else
 | 
						||
      ae = esercizi.date2esc(ad);
 | 
						||
  }
 | 
						||
  CHECKD(esercizi.exist(ae), "Anno di esercizio fantasioso: ", ae);
 | 
						||
  
 | 
						||
  const TDate& inizio_esercizio = esercizi[ae].inizio();
 | 
						||
  _da_data = dd.ok() ? dd : inizio_esercizio;
 | 
						||
  _a_data  = ad.ok() ? ad : esercizi[ae].fine();
 | 
						||
 | 
						||
  const bool test_caus = !(dc.blank() && ac.blank());
 | 
						||
  _da_caus = dc;
 | 
						||
  _a_caus = ac.blank() ? "zzz" : ac;       // Se vuota sceglie la massima causale
 | 
						||
  _provvis = provvis;
 | 
						||
  
 | 
						||
  TDate max_data_reg = _a_data;
 | 
						||
  long num_giorni = _a_data - inizio_esercizio + 1;
 | 
						||
  if (_esercizio > 0) 
 | 
						||
  {
 | 
						||
    const int succ = esercizi.next(ae);   
 | 
						||
    if (succ > 0)
 | 
						||
    {
 | 
						||
      max_data_reg = esercizi[succ].fine();
 | 
						||
      num_giorni += 30;
 | 
						||
    }
 | 
						||
    else
 | 
						||
      max_data_reg = esercizi[ae].fine();
 | 
						||
  }
 | 
						||
 | 
						||
  // Valori dei saldi fino alla data di inizio stampa:
 | 
						||
  // Vengono inizializzati con i saldi iniziali dell'esercizio,
 | 
						||
  // poi verranno sommati gli importi dei movimenti che
 | 
						||
  // vanno dall'inizio dell'esercizio al giorno precedente
 | 
						||
  // la data di inizio stampa
 | 
						||
 | 
						||
  TBalance saldo(_conto, ae, true, provvis);
 | 
						||
  _pdare_ini  = saldo.progressivo_dare_iniziale();
 | 
						||
  _pavere_ini = saldo.progressivo_avere_iniziale();
 | 
						||
  
 | 
						||
  // Valori dei saldi finali:
 | 
						||
  // Comprendono i movimenti di apertura, chiusura ed i progressivi attuali
 | 
						||
  saldo.read(_conto, ae, false, provvis);
 | 
						||
  _pdare_fin  = saldo.progressivo_dare_finale();
 | 
						||
  _pavere_fin = saldo.progressivo_avere_finale();
 | 
						||
  
 | 
						||
  // Valori dei saldi del perido in esame:
 | 
						||
  // Vengono inizializzati a zero e poi si incrementa man mano
 | 
						||
  // coi valori degli importi dei movimenti compresi nei
 | 
						||
  // limiti della stampa
 | 
						||
  _pdare_per = _pavere_per = ZERO;
 | 
						||
  
 | 
						||
  const TRecfield rmov_datareg   (rmov_rec, RMV_DATAREG);
 | 
						||
  const TRecfield rmov_numreg    (rmov_rec, RMV_NUMREG);
 | 
						||
  const TRecfield rmov_gruppo    (rmov_rec, RMV_GRUPPO);  
 | 
						||
  const TRecfield rmov_conto     (rmov_rec, RMV_CONTO);
 | 
						||
  const TRecfield rmov_sottoconto(rmov_rec, RMV_SOTTOCONTO);
 | 
						||
  const TRecfield rmov_sezione   (rmov_rec, RMV_SEZIONE);  
 | 
						||
  const TRecfield rmov_importo   (rmov_rec, RMV_IMPORTO);  
 | 
						||
  
 | 
						||
  const TRecfield mov_datacomp   (mov_rec, MOV_DATACOMP);  
 | 
						||
  const TRecfield mov_provvis    (mov_rec, MOV_PROVVIS);  
 | 
						||
  const TRecfield mov_codcaus    (mov_rec, MOV_CODCAUS);  
 | 
						||
  
 | 
						||
#ifdef DBG
 | 
						||
  long num_rec = 0;                                    
 | 
						||
  const clock_t clock_start = clock();
 | 
						||
#endif  
 | 
						||
 | 
						||
  rmov_rec.zero();
 | 
						||
  conto.put(rmov_rec);
 | 
						||
  TRectype darow(rmov_rec), arow(rmov_rec);
 | 
						||
  darow.put(RMV_DATAREG, inizio_esercizio);
 | 
						||
  arow.put(RMV_DATAREG, max_data_reg);
 | 
						||
  TCursor cur(&rel(), "", 2, &darow, &arow);
 | 
						||
  const TRecnotype totrows = cur.items();
 | 
						||
  cur.freeze();
 | 
						||
 | 
						||
  TString caption(80);
 | 
						||
  caption.format(FR("Caricamento mastrino %03d.%03d.%06ld"), 
 | 
						||
                 _conto.gruppo(), _conto.conto(), _conto.sottoconto());
 | 
						||
  TProgind pi(totrows, caption, false, true);
 | 
						||
  
 | 
						||
  for (cur = 0L; cur.pos() < totrows; ++cur)
 | 
						||
  {
 | 
						||
    pi.addstatus(1);
 | 
						||
#ifdef DBG
 | 
						||
    num_rec++;
 | 
						||
    if ((num_rec & 0x7F) == 0)
 | 
						||
    {             
 | 
						||
      const double sec = (clock() - clock_start) / CLOCKS_PER_SEC;
 | 
						||
      if (sec > 0.0)
 | 
						||
      {
 | 
						||
        TString80 msg;
 | 
						||
        msg.format("%ld records at %ld rec/sec", num_rec, long(num_rec/sec));
 | 
						||
        pi.set_text(msg);
 | 
						||
      }  
 | 
						||
    }
 | 
						||
#endif    
 | 
						||
    
 | 
						||
    // Ignora eventualmente i movimenti provvisori
 | 
						||
    if (!_provvis)
 | 
						||
    {
 | 
						||
      const char is_provvis = *(const char*)mov_provvis;
 | 
						||
      if (is_provvis > ' ')  
 | 
						||
        continue;
 | 
						||
    }
 | 
						||
    
 | 
						||
    const TDate data_corrente = _esercizio <= 0 ? rmov_datareg : TDate((const char*)mov_datacomp);
 | 
						||
    if (data_corrente > _a_data)
 | 
						||
      continue;
 | 
						||
      
 | 
						||
    const char sezione = *((const char*)rmov_sezione);                 
 | 
						||
    const real importo((const char*)rmov_importo);
 | 
						||
                           
 | 
						||
    if (data_corrente < _da_data)                       
 | 
						||
    {                      
 | 
						||
      if (data_corrente >= inizio_esercizio)
 | 
						||
      {
 | 
						||
        if (sezione == 'D')                       
 | 
						||
          _pdare_ini += importo;
 | 
						||
        else  
 | 
						||
          _pavere_ini += importo;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    else
 | 
						||
    { 
 | 
						||
      if (sezione == 'D')                       
 | 
						||
        _pdare_per += importo;
 | 
						||
      else  
 | 
						||
        _pavere_per += importo;
 | 
						||
 | 
						||
      // Controlla che la causale sia nei limiti  
 | 
						||
      if (test_caus)
 | 
						||
      {
 | 
						||
        const bool ok = _da_caus <= mov_codcaus && _a_caus >= mov_codcaus;
 | 
						||
        if (!ok)
 | 
						||
          continue;
 | 
						||
      }  
 | 
						||
      
 | 
						||
      TRiga_mastrino* r = new TRiga_mastrino(riga_mastrino, 
 | 
						||
                                             rmov().recno(), mov().recno(),
 | 
						||
                                             _pdare_per, _pavere_per, rmov_datareg);  
 | 
						||
      _riga.append(r);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  // Mi sposto all'inizio per far funzionare bene da subito il metodo riga(0)  
 | 
						||
  mov().first();   
 | 
						||
  rmov().first();
 | 
						||
}
 | 
						||
 | 
						||
void TMastrino::reread()
 | 
						||
{
 | 
						||
  read(_conto, _esercizio, _da_data, _a_data, _da_caus, _a_caus, _provvis);
 | 
						||
} 
 | 
						||
 | 
						||
void TMastrino::position_rel(long n)
 | 
						||
{
 | 
						||
  const TRiga_mastrino& r = row(n);
 | 
						||
  if (rmov().recno() != r.rmov())
 | 
						||
    rmov().readat(r.rmov());
 | 
						||
  if (mov().recno() != r.mov())
 | 
						||
    mov().readat(r.mov());
 | 
						||
}
 | 
						||
 | 
						||
const TRectype& TMastrino::riga(long n)
 | 
						||
{
 | 
						||
  position_rel(n);
 | 
						||
  return rmov().curr();  
 | 
						||
}
 | 
						||
 | 
						||
const TRectype& TMastrino::testata(long n)
 | 
						||
{
 | 
						||
  position_rel(n);
 | 
						||
  return mov().curr();  
 | 
						||
}
 | 
						||
 | 
						||
TImporto TMastrino::saldo_iniziale() const
 | 
						||
{
 | 
						||
  TImporto s('D', _pdare_ini - _pavere_ini);
 | 
						||
  return s.normalize();
 | 
						||
}
 | 
						||
 | 
						||
TImporto TMastrino::saldo_finale() const
 | 
						||
{
 | 
						||
  TImporto s('D', _pdare_fin - _pavere_fin);
 | 
						||
  return s.normalize();
 | 
						||
}
 | 
						||
 | 
						||
TImporto TMastrino::saldo_periodo() const
 | 
						||
{
 | 
						||
  TImporto s('D', progressivo_dare_periodo() - progressivo_avere_periodo());
 | 
						||
  return s.normalize();
 | 
						||
}
 | 
						||
 | 
						||
bool TMastrino::expandable(long rec) const
 | 
						||
{   
 | 
						||
  bool e = false;   
 | 
						||
  if (rec >= 0 && rec < items())
 | 
						||
  {
 | 
						||
    if (row(rec).tipo() == riga_mastrino)
 | 
						||
    {
 | 
						||
      if (rec < items()-1)
 | 
						||
        e = row(rec+1).tipo() != riga_contropartita;
 | 
						||
      else
 | 
						||
        e = true;  
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  return e;
 | 
						||
}
 | 
						||
 | 
						||
// Genera le righe di contropartita di una riga del mastrino
 | 
						||
bool TMastrino::expand(long rec)
 | 
						||
{
 | 
						||
  bool ok = expandable(rec);
 | 
						||
  if (ok)
 | 
						||
  {   
 | 
						||
    const TRectype& head = testata(rec);               // Testata movimento
 | 
						||
    const long numreg = head.get_long(RMV_NUMREG);     // Numero di registrazione
 | 
						||
    const int numrig = riga(rec).get_int(RMV_NUMRIG);  // Numero riga contabile
 | 
						||
    const TDate datareg = head.get(MOV_DATAREG);       // Data di registrazione
 | 
						||
    
 | 
						||
    rmov().setkey(1);                                  // Usa chiave NUMREG+NUMRIG
 | 
						||
    TRectype& curr = rmov().curr();                    // Record corrente
 | 
						||
    
 | 
						||
    const TRecfield rnumreg (curr, RMV_NUMREG);        // Numero di registrazione corrente
 | 
						||
    const TRecfield rnumrig (curr, RMV_NUMRIG);        // Numero di riga corrente
 | 
						||
    const TRecfield rsezione(curr, RMV_SEZIONE);       // Sezione Dare/Avere
 | 
						||
    const TRecfield rimporto(curr, RMV_IMPORTO);       // Importo della riga
 | 
						||
    
 | 
						||
    int err = NOERR;
 | 
						||
    if (numrig != 1)    // Se non e' gia' posizionato grazie a riga(rec)
 | 
						||
    {
 | 
						||
      curr.zero();                                     // Azzera record corrente
 | 
						||
      curr.put(RMV_NUMREG, numreg);                    // Inizializza la chiave parziale
 | 
						||
      err = rmov().read(_isgteq);                      // Cerca la prima riga del movimento
 | 
						||
    }  
 | 
						||
    for (; err == NOERR; err = rmov().next())          // Scandisce righe movimento
 | 
						||
    {
 | 
						||
      if (numreg != (long)rnumreg)                     // Controlla validita' numero 
 | 
						||
        break;                               
 | 
						||
 | 
						||
      if (numrig != (int)rnumrig)                      // Ignora la riga gia' presente
 | 
						||
      {
 | 
						||
        real dare, avere;                              // Costruisce importo della riga
 | 
						||
        if (*(const char*)rsezione == 'D')  
 | 
						||
          dare = rimporto;                     
 | 
						||
        else
 | 
						||
          avere = rimporto;
 | 
						||
        // Aggiunge una riga di contropartita al mastrino
 | 
						||
        TRiga_mastrino* r = new TRiga_mastrino(riga_contropartita, 
 | 
						||
                                               rmov().recno(), mov().recno(),
 | 
						||
                                               dare, avere, datareg);  
 | 
						||
        _riga.append(r, rec++);
 | 
						||
      }  
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Elimina le righe di contropartita di una riga del mastrino
 | 
						||
bool TMastrino::collapse(long rec)
 | 
						||
{       
 | 
						||
  bool ok = true;                        // Posso eliminare?
 | 
						||
 | 
						||
  if (rec < 0)
 | 
						||
  {
 | 
						||
    for (long i = last(); i >= 0; i = pred(i))
 | 
						||
      collapse(i);
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (row(rec).tipo() != riga_mastrino)  // Se non sono su una riga mastrino ...
 | 
						||
      rec = pred(rec, riga_mastrino);      // ... mi sposto sulla precedente riga mastrino
 | 
						||
    ok = !expandable(rec);                 // Controlla che sia possibile
 | 
						||
    if (ok)                                // Posso effetivamente procedere
 | 
						||
    {        
 | 
						||
      rec++;                               // Elimino ogni riga contropartita successiva
 | 
						||
      while (rec < items() && row(rec).tipo() != riga_mastrino)
 | 
						||
        _riga.remove(rec);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TGrid_control
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TGrid_control;
 | 
						||
 | 
						||
class TGrid_cell : public TFixed_string
 | 
						||
{
 | 
						||
  XI_EVENT* _xiev;
 | 
						||
 | 
						||
public:                    
 | 
						||
  TString& set(const char* txt);
 | 
						||
  TString& set(long num);
 | 
						||
  void set_icon(int id);
 | 
						||
  void show_button(bool on = true);
 | 
						||
  void hide_button() { show_button(false); }
 | 
						||
  void set_back_color(COLOR col);
 | 
						||
  void set_fore_color(COLOR col);
 | 
						||
  void set_colors(COLOR back, COLOR fore);
 | 
						||
  
 | 
						||
  short get_column() const { return _xiev->v.cell_request.col_nbr; }
 | 
						||
  
 | 
						||
  TString& operator = (const char* str) { return set(str); }
 | 
						||
  TString& operator = (const TString& str) { return set(str); }
 | 
						||
 | 
						||
  XI_EVENT* event() { return _xiev; }
 | 
						||
 | 
						||
  TGrid_cell(XI_EVENT* xiev);
 | 
						||
  virtual ~TGrid_cell() { }
 | 
						||
};
 | 
						||
 | 
						||
class TGrid_field : public TOperable_field
 | 
						||
{     
 | 
						||
protected: // TMask_field
 | 
						||
  virtual void create(WINDOW parent);
 | 
						||
  virtual void parse_head(TScanner& scanner);
 | 
						||
  virtual bool parse_item(TScanner& scanner);
 | 
						||
  virtual word class_id() const;
 | 
						||
 | 
						||
public:
 | 
						||
  TGrid_control& grid() const { return (TGrid_control&)*_ctl; }
 | 
						||
 | 
						||
  virtual bool handler(XI_EVENT* xiev);
 | 
						||
  virtual long items() const;
 | 
						||
  virtual void cell_request(long rec, short id, TGrid_cell& cell);
 | 
						||
 | 
						||
  virtual bool on_record(long rec)  { return true; }
 | 
						||
  virtual bool off_record(long rec) { return true; }
 | 
						||
  virtual bool on_resize_column(short cid, int new_size) { return true; }
 | 
						||
  virtual void on_dbl_cell(long rec, short id) { }
 | 
						||
  virtual void on_grid_button() { } 
 | 
						||
  virtual void on_record_button(long rec) { }
 | 
						||
  virtual void on_cell_button(long rec, short cid) { }
 | 
						||
 | 
						||
  long selected() const;
 | 
						||
  void update(long n = -1);
 | 
						||
  int visible_rows() const;
 | 
						||
  bool select(long rec);
 | 
						||
  
 | 
						||
  void reset_columns_order();
 | 
						||
  void save_columns_order() const; 
 | 
						||
  
 | 
						||
  TGrid_field(TMask* m);
 | 
						||
  virtual ~TGrid_field() { }
 | 
						||
};
 | 
						||
 | 
						||
class TGrid_control : public TControl
 | 
						||
{
 | 
						||
  enum grid_control_constants { MAX_COL = 64 };
 | 
						||
 | 
						||
  long _cur_rec;
 | 
						||
  bool _read_only;
 | 
						||
  
 | 
						||
  // @cmember:(INTERNAL) Tipo di ogni colonna
 | 
						||
  byte _type[MAX_COL];
 | 
						||
  
 | 
						||
  TGrid_field* _grid;
 | 
						||
  
 | 
						||
  int _default_width[MAX_COL];
 | 
						||
  int _columns_order;
 | 
						||
 | 
						||
protected:  // TControl
 | 
						||
  //@cmember Gestisce gli eventi delle celle
 | 
						||
  virtual bool event_handler(XI_OBJ* itf, XI_EVENT* xiev);
 | 
						||
  
 | 
						||
  //@cmember Chiama gli handlers opportuni per verificare il cambio record
 | 
						||
  bool try_to_select(long rec) const;  
 | 
						||
 | 
						||
protected:  
 | 
						||
  //@cmember Ritorna il numero totale di righe
 | 
						||
  long items() const { return _grid->items(); }
 | 
						||
  
 | 
						||
  //@cmember Converte un record nella eventuale riga corrispondente a video
 | 
						||
  int rec2row(long rec) const;
 | 
						||
  
 | 
						||
  //@cmember Converte una riga a video nell'eventuale record corrispondente
 | 
						||
  long row2rec(int row) const;
 | 
						||
  
 | 
						||
  //@cmember Converte un indice di colonna nel corrispondente id
 | 
						||
  short int col2cid(int pos) const;
 | 
						||
  
 | 
						||
  void update_selection(XI_EVENT* xiev);
 | 
						||
 | 
						||
  void set_columns_order(TToken_string* order);
 | 
						||
  
 | 
						||
  XI_OBJ* find_column(const char* head) const;
 | 
						||
 | 
						||
public:                   
 | 
						||
  long selected() const { return _cur_rec; }
 | 
						||
  bool select(long n);
 | 
						||
  
 | 
						||
  int visible_rows() const;
 | 
						||
    
 | 
						||
  XI_OBJ* find_column(short cid) const;
 | 
						||
  byte& column_type(int c) { CHECKD(c >= 0 && c < MAX_COL, "Bad column ", c); return _type[c]; }
 | 
						||
  void show_column(short cid, bool on);
 | 
						||
 | 
						||
  void update(long n = -1);
 | 
						||
  bool is_visible(long rec) const;
 | 
						||
  
 | 
						||
  void load_columns_order();
 | 
						||
  void save_columns_order() const; 
 | 
						||
  void reset_columns_order() { set_columns_order(NULL); }
 | 
						||
  
 | 
						||
  TGrid_control(WINDOW parent, short cid, 
 | 
						||
                short x, short y, short dx, short dy,              
 | 
						||
                const char* flags, const char* head,
 | 
						||
                TGrid_field* owner);
 | 
						||
  virtual ~TGrid_control() {}
 | 
						||
};
 | 
						||
 | 
						||
 | 
						||
TGrid_control::TGrid_control(
 | 
						||
  WINDOW parent,         // @parm Finestra alla quale appartiene lo spreadsheet
 | 
						||
  short cid,             // @parm Identificatore
 | 
						||
  short x,               // @parm Coordinata x (in caratteri) nel quale posizionare lo spreadsheet
 | 
						||
  short y,               // @parm Coordinata y (in caratteri) nel quale posizionare lo spreadsheet
 | 
						||
  short dx,              // @parm Larghezza (in caratteri) dello spreasheet
 | 
						||
  short dy,              // @parm Lunghezza (in caratteri) dello spreasheet
 | 
						||
  const char* flags,     // @parm Flags di abilitazione
 | 
						||
  const char* head,      // @parm Titolo delle colonne
 | 
						||
  TGrid_field* owner)
 | 
						||
              : _grid(owner), _cur_rec(-1), _columns_order(0)
 | 
						||
{ 
 | 
						||
  _read_only        = false;
 | 
						||
  bool auto_num     = false;
 | 
						||
  bool multi_line   = false;
 | 
						||
  int lines_in_cell = 1;
 | 
						||
  
 | 
						||
  for (const char* f = flags; *f; f++)
 | 
						||
  {
 | 
						||
    switch(*f)
 | 
						||
    {       
 | 
						||
    case 'A':
 | 
						||
      auto_num = true;
 | 
						||
      break;
 | 
						||
    case 'D': 
 | 
						||
      _read_only = true;
 | 
						||
      break;
 | 
						||
    case 'M': 
 | 
						||
      multi_line = true; 
 | 
						||
      lines_in_cell = (int)xi_get_pref(XI_PREF_DEFAULT_MAX_LINES_IN_CELL);
 | 
						||
      break;
 | 
						||
    case '2':
 | 
						||
    case '3':
 | 
						||
    case '4':
 | 
						||
    case '5':               
 | 
						||
      if (multi_line)
 | 
						||
        lines_in_cell = *f - '0'; 
 | 
						||
      break;
 | 
						||
    default:  
 | 
						||
      break;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  const int NUMBER_WIDTH = auto_num ? 7 : 1;
 | 
						||
  short v_width[MAX_COL];
 | 
						||
  short m_width[MAX_COL];
 | 
						||
  int fixed_columns = 1;                               // Number of fixed columns
 | 
						||
  int lines_in_header = 1;                             // Number of header lines
 | 
						||
  
 | 
						||
  // Calcolo larghezza massima tabella
 | 
						||
  TToken_string header(head);
 | 
						||
  TToken_string new_header(256);
 | 
						||
  int i = 0;
 | 
						||
  int f_width = NUMBER_WIDTH;                          // Stima larghezza colonne fisse
 | 
						||
  int max_width = f_width;                             // Stima larghezza della colonna piu' grande
 | 
						||
  const char* h;
 | 
						||
 | 
						||
  for (h = header.get(); h; h = header.get(), i++)
 | 
						||
  {
 | 
						||
    CHECKD(i < MAX_COL, "Tu meni calumns in scit: ", i);
 | 
						||
    _type[i] = ' ';
 | 
						||
    
 | 
						||
    TFixed_string testa(esc(h));
 | 
						||
    const bool multiple = testa.find('\n') > 0;
 | 
						||
    if (multiple)
 | 
						||
      lines_in_header = 2;
 | 
						||
 | 
						||
    const int at = testa.find('@');
 | 
						||
    int v = testa.len();                             // Video width
 | 
						||
    if (at >= 0)
 | 
						||
    {
 | 
						||
      const TString& wi = testa.mid(at+1);
 | 
						||
      const int video = atoi(wi);
 | 
						||
      if (video > 0) v = video;
 | 
						||
      if (wi.find('F') >= 0) 
 | 
						||
      {
 | 
						||
        fixed_columns = i+2;
 | 
						||
        f_width += v+1;
 | 
						||
      }    
 | 
						||
      if (wi.find('R') >= 0)
 | 
						||
        _type[i] = 'R';
 | 
						||
 | 
						||
      testa.cut(at);
 | 
						||
    } 
 | 
						||
    
 | 
						||
    v++;                                                 
 | 
						||
    // memory width of column
 | 
						||
    m_width[i] = v * lines_in_cell;         
 | 
						||
    if (v > 64) v = 64;
 | 
						||
    v_width[i] = v;
 | 
						||
    if (v_width[i] > max_width) 
 | 
						||
      max_width = v_width[i];
 | 
						||
    new_header.add(testa);
 | 
						||
  }
 | 
						||
  
 | 
						||
  // Calcola rettangolo massimo per lo sheet
 | 
						||
  XI_OBJ* itf = get_interface(parent);     
 | 
						||
  XI_RCT rct = coord2rct(itf, x, y, dx, dy);
 | 
						||
  rct.right -= 2*XI_FU_MULTIPLE;           // toglie scroll-bar
 | 
						||
 
 | 
						||
  // Controlla se ci sono troppe colonne fisse
 | 
						||
  if ((f_width+max_width)*XI_FU_MULTIPLE > rct.right)
 | 
						||
    fixed_columns = 1;
 | 
						||
  
 | 
						||
  long list_attr = XI_ATR_ENABLED | XI_ATR_VISIBLE;
 | 
						||
  // if (_read_only) list_attr |= XI_ATR_NAVIGATE;
 | 
						||
 | 
						||
  XI_OBJ_DEF* listdef = xi_add_list_def(NULL, cid,
 | 
						||
                                        rct.top, rct.left, rct.bottom-rct.top,
 | 
						||
                                        list_attr,
 | 
						||
                                        NORMAL_COLOR, NORMAL_BACK_COLOR,     // normal
 | 
						||
                                        DISABLED_COLOR, DISABLED_BACK_COLOR, // disabled
 | 
						||
                                        FOCUS_COLOR,                         // active
 | 
						||
                                        0);
 | 
						||
                                        
 | 
						||
  listdef->app_data = (long)this;
 | 
						||
  
 | 
						||
  XI_LIST_DEF* l = listdef->v.list;
 | 
						||
  l->min_heading_height = xi_button_calc_height_font(xi_get_system_font()) * lines_in_header;
 | 
						||
  l->sizable_columns    = true;
 | 
						||
  l->movable_columns    = true;
 | 
						||
  l->fixed_columns      = fixed_columns;
 | 
						||
  l->max_lines_in_cell  = lines_in_cell;
 | 
						||
  l->scroll_bar         = true;
 | 
						||
  l->scroll_bar_button  = true;
 | 
						||
  l->white_space_color  = MASK_DARK_COLOR;
 | 
						||
  l->rule_color         = MASK_DARK_COLOR;
 | 
						||
 | 
						||
  if (_read_only)
 | 
						||
  {
 | 
						||
    l->single_select = true;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    l->active_back_color = FOCUS_BACK_COLOR;
 | 
						||
  }
 | 
						||
 | 
						||
  // Definizione della prima colonna (numero di riga)
 | 
						||
  const long attr = XI_ATR_VISIBLE | XI_ATR_RJUST | XI_ATR_SELECTABLE;                                            
 | 
						||
  XI_OBJ_DEF* coldef = xi_add_column_def(listdef, FIRST_FIELD+1000-1, attr, 0, 
 | 
						||
                                         NUMBER_WIDTH * XI_FU_MULTIPLE, NUMBER_WIDTH , "");
 | 
						||
  
 | 
						||
  coldef->app_data = (long)this;            
 | 
						||
  XI_COLUMN_DEF* cd = coldef->v.column;
 | 
						||
  cd->heading_platform = true;
 | 
						||
  cd->column_platform  = true;
 | 
						||
 | 
						||
  for (h = new_header.get(0), i = 0; h; h = new_header.get(), i++)
 | 
						||
  {                  
 | 
						||
    long attr = XI_ATR_VISIBLE | XI_ATR_ENABLED | XI_ATR_AUTOSCROLL; 
 | 
						||
    if (_read_only)
 | 
						||
      attr |= XI_ATR_READONLY | XI_ATR_SELECTABLE;
 | 
						||
    if (_type[i] == 'R') 
 | 
						||
      attr |= XI_ATR_RJUST;
 | 
						||
    coldef = xi_add_column_def(listdef, FIRST_FIELD+i+1000, attr, i+1, 
 | 
						||
                               v_width[i] * XI_FU_MULTIPLE, m_width[i], (char*)h);
 | 
						||
 | 
						||
    coldef->app_data = (long)this;
 | 
						||
    cd = coldef->v.column;  
 | 
						||
    cd->heading_platform = true;
 | 
						||
    cd->center_heading = true;
 | 
						||
    if (multi_line)
 | 
						||
      cd->wrap_text = _type[i] != 'R'; 
 | 
						||
  }
 | 
						||
                                
 | 
						||
  XI_RCT rd; xi_get_def_rect(listdef, &rd);
 | 
						||
  if ((rd.right - rd.left) > (rct.right - rct.left))
 | 
						||
    l->width = rct.right - rct.left;
 | 
						||
 | 
						||
  _obj = xi_create(itf, listdef);     // Create the whole thing!
 | 
						||
  xi_dequeue();                       // Flush events in XOL
 | 
						||
  xi_tree_free(listdef);              // Free definitions
 | 
						||
               
 | 
						||
  CHECKD(_obj, "Can't create list control ", cid);   
 | 
						||
  update_tab_cid();
 | 
						||
  
 | 
						||
  int num = 0;
 | 
						||
  XI_OBJ** column = xi_get_member_list(_obj, &num);
 | 
						||
  for (i = 0; i < num; i++) 
 | 
						||
  {
 | 
						||
    xi_get_rect(column[i], &rd);
 | 
						||
    _default_width[i] = rd.right - rd.left;
 | 
						||
  }
 | 
						||
} 
 | 
						||
 | 
						||
// Converts a record number in the correspondig row number
 | 
						||
int TGrid_control::rec2row(long record) const
 | 
						||
{
 | 
						||
  int rows;
 | 
						||
  const long* rec = xi_get_list_info(_obj, &rows);
 | 
						||
  int r = rows > 0 ? int(record - rec[0]) : -1;
 | 
						||
  if (r < 0 || r >= rows) 
 | 
						||
    r = -1;
 | 
						||
  return r;
 | 
						||
}
 | 
						||
 | 
						||
// Converts a row number in the correspondig record number
 | 
						||
long TGrid_control::row2rec(int row) const
 | 
						||
{
 | 
						||
  CHECK(row >= 0, "Negative grid row?");
 | 
						||
 | 
						||
  int rows;
 | 
						||
  const long* handle = xi_get_list_info(_obj, &rows);
 | 
						||
  
 | 
						||
  long rec;
 | 
						||
  if (rows > 0)
 | 
						||
  {
 | 
						||
    if (row >= rows) 
 | 
						||
      rec = handle[rows-1] + row - rows + 1;
 | 
						||
    else
 | 
						||
      rec = handle[row];
 | 
						||
  }
 | 
						||
  else
 | 
						||
    rec = -1;
 | 
						||
 | 
						||
  if (rec < 0 || rec >= items())
 | 
						||
    rec = -1;
 | 
						||
  
 | 
						||
  return rec;
 | 
						||
} 
 | 
						||
 | 
						||
int TGrid_control::visible_rows() const
 | 
						||
{
 | 
						||
  return xi_get_visible_rows(_obj, NULL, NULL);
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_control::is_visible(long rec) const
 | 
						||
{ 
 | 
						||
  int first = 0, last = 0;
 | 
						||
  xi_get_visible_rows(_obj, &first, &last);
 | 
						||
 | 
						||
  int rows = 0;
 | 
						||
  const long* handle = xi_get_list_info(_obj, &rows);
 | 
						||
  
 | 
						||
  bool yes = rec >= handle[first] && rec <= handle[last];
 | 
						||
  return yes;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TGrid_control::update(long n)
 | 
						||
{
 | 
						||
  if (n >= 0)
 | 
						||
  {
 | 
						||
    const int riga = rec2row(n);
 | 
						||
    if (riga >= 0)
 | 
						||
    {                 
 | 
						||
      XI_OBJ row;
 | 
						||
      XI_MAKE_ROW(&row, _obj, riga);
 | 
						||
      xi_cell_request(&row);           
 | 
						||
    }
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    int num = 0;
 | 
						||
    const long* handle = xi_get_list_info(_obj, &num);
 | 
						||
 | 
						||
    bool scroll_first = items() == 0;
 | 
						||
    if (!scroll_first)
 | 
						||
    {
 | 
						||
      int first = 0, last = 0;
 | 
						||
      xi_get_visible_rows(_obj, &first, &last);   
 | 
						||
      n = handle[first];
 | 
						||
      scroll_first = n > items();
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (scroll_first)
 | 
						||
      xi_scroll(_obj, XI_SCROLL_FIRST);
 | 
						||
    else
 | 
						||
      xi_scroll_rec(_obj, n, NORMAL_COLOR, XI_ATR_ENABLED, 0);
 | 
						||
  }  
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_control::select(long rec)
 | 
						||
{ 
 | 
						||
  bool ok, sel;
 | 
						||
  if (rec >= 0)               
 | 
						||
  {
 | 
						||
    ok = try_to_select(rec);
 | 
						||
    sel = ok;
 | 
						||
  }  
 | 
						||
  else  
 | 
						||
  {
 | 
						||
    ok = _cur_rec >= 0 && _cur_rec < items() && _grid->off_record(_cur_rec);
 | 
						||
    sel = false;
 | 
						||
  }  
 | 
						||
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    if (sel)
 | 
						||
    {                                          
 | 
						||
      int first, last;
 | 
						||
      xi_get_visible_rows(_obj, &first, &last);
 | 
						||
      // Controllo che la nuova riga sia completamente visibile
 | 
						||
      const int next_row = rec2row(rec);      
 | 
						||
      if (next_row >= first && next_row <= last) 
 | 
						||
      {   
 | 
						||
        if (_read_only)
 | 
						||
        {
 | 
						||
          XI_OBJ riga; XI_MAKE_ROW(&riga, _obj, next_row);
 | 
						||
          long attr = xi_get_attrib(&riga);
 | 
						||
          attr |= XI_ATR_SELECTED;
 | 
						||
          xi_set_attrib(&riga, attr);
 | 
						||
        }  
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        long attr = XI_ATR_ENABLED;
 | 
						||
        if (_read_only)
 | 
						||
          attr |= XI_ATR_SELECTED;
 | 
						||
        xi_scroll_rec(_obj, rec, NORMAL_COLOR, attr, 0);
 | 
						||
      }
 | 
						||
  
 | 
						||
      if (!_read_only)
 | 
						||
      { 
 | 
						||
        const int next_row = rec2row(rec);
 | 
						||
        XI_OBJ cella; XI_MAKE_CELL(&cella, _obj, next_row, 1);
 | 
						||
        xi_set_focus(&cella);
 | 
						||
      }
 | 
						||
    }  // end if (sel)
 | 
						||
    
 | 
						||
    // Deseleziona record precedente se ancora visibile
 | 
						||
    if (_read_only)
 | 
						||
    {                                 
 | 
						||
      const int cur_row = rec2row(_cur_rec);
 | 
						||
      if (cur_row >= 0)
 | 
						||
      {
 | 
						||
        XI_OBJ riga; XI_MAKE_ROW(&riga, _obj, cur_row);
 | 
						||
        long attr = xi_get_attrib(&riga);
 | 
						||
        attr &= ~XI_ATR_SELECTED;     
 | 
						||
        xi_set_attrib(&riga, attr);
 | 
						||
      }
 | 
						||
      xi_dequeue();
 | 
						||
    }
 | 
						||
  
 | 
						||
    if (rec < 0 || rec >= items())
 | 
						||
      rec = -1;
 | 
						||
    _cur_rec = rec;
 | 
						||
  }           // end if (ok)
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
short TGrid_control::col2cid(int pos) const
 | 
						||
{
 | 
						||
  int num;
 | 
						||
  XI_OBJ** column = xi_get_member_list(_obj, &num);
 | 
						||
  CHECKD(pos >= 0 && pos < num, "Bad column ", pos);
 | 
						||
  const short cid = column[pos]->cid - 1000;
 | 
						||
  return cid;
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_control::try_to_select(long rec) const
 | 
						||
{  
 | 
						||
  bool ok = rec >= 0 && rec < items();
 | 
						||
  if (ok && rec != _cur_rec)
 | 
						||
  {         
 | 
						||
    if (_cur_rec >= 0 && _cur_rec < items())
 | 
						||
      ok = _grid->off_record(_cur_rec);  
 | 
						||
    if (ok)
 | 
						||
      ok = _grid->on_record(rec);
 | 
						||
  }              
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_control::update_selection(XI_EVENT* xiev)
 | 
						||
{
 | 
						||
  const bool is_curr = xiev->v.rec_request.data_rec == _cur_rec;
 | 
						||
  if (_read_only)
 | 
						||
  {     
 | 
						||
/*
 | 
						||
    if (is_curr)
 | 
						||
      xiev->v.rec_request.attrib |= XI_ATR_SELECTED;
 | 
						||
    else
 | 
						||
      xiev->v.rec_request.attrib &= ~XI_ATR_SELECTED;
 | 
						||
*/
 | 
						||
  }
 | 
						||
  else
 | 
						||
    xiev->v.rec_request.has_focus = is_curr;
 | 
						||
}
 | 
						||
 | 
						||
// Certified 75%
 | 
						||
bool TGrid_control::event_handler(XI_OBJ* itf, XI_EVENT *xiev)
 | 
						||
{
 | 
						||
  BOOLEAN& refused = xiev->refused;   
 | 
						||
  
 | 
						||
  const bool handled = _grid->handler(xiev);
 | 
						||
  if (handled)
 | 
						||
    return !refused;
 | 
						||
 | 
						||
  switch (xiev->type)
 | 
						||
  {
 | 
						||
  case XIE_GET_FIRST:
 | 
						||
    if (items() > 0L)
 | 
						||
    {
 | 
						||
      long n = items() * (long)xiev->v.rec_request.percent / 100L;
 | 
						||
      if (n < 0L) n = 0L;
 | 
						||
      xiev->v.rec_request.data_rec = n;
 | 
						||
      update_selection(xiev);
 | 
						||
    }
 | 
						||
    else
 | 
						||
      refused = true;
 | 
						||
    break;
 | 
						||
  case XIE_GET_LAST:
 | 
						||
    xiev->v.rec_request.data_rec = items()-1;
 | 
						||
    update_selection(xiev);
 | 
						||
    break;
 | 
						||
  case XIE_GET_PREV:
 | 
						||
  case XIE_GET_NEXT:
 | 
						||
    {
 | 
						||
      const long n = xiev->v.rec_request.spec_rec + (xiev->type == XIE_GET_NEXT ? +1 : -1) ;
 | 
						||
      if (n >= 0 && n < items())
 | 
						||
      {
 | 
						||
        xiev->v.rec_request.data_rec = n;
 | 
						||
        update_selection(xiev);
 | 
						||
      }  
 | 
						||
      else
 | 
						||
        refused = true;
 | 
						||
      // Altrimenti sbaglia a ridisegnare le righe della DBService!
 | 
						||
      XI_RCT rct; xi_get_rect(_obj, &rct);
 | 
						||
      xi_invalidate_rect(xi_get_window(_obj), &rct); 
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case XIE_GET_PERCENT:
 | 
						||
    {
 | 
						||
      const long rec = xiev->v.get_percent.record;
 | 
						||
      long n = items(); if (n <= 0) n = 1;
 | 
						||
      xiev->v.get_percent.percent = short(rec * 100L / n);
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case XIE_COL_MOVE:           
 | 
						||
    // Rifiuta di spostare una colonna nelle o dalle colonne fisse
 | 
						||
    if (xiev->v.column.in_fixed || 
 | 
						||
        xiev->v.column.col_nbr < xi_get_fixed_columns(xiev->v.column.list))
 | 
						||
      refused = true;
 | 
						||
    else
 | 
						||
      _columns_order = 1;  
 | 
						||
    break;  
 | 
						||
  case XIE_COL_SIZE:            
 | 
						||
    {
 | 
						||
      const short cid = col2cid(xiev->v.column.col_nbr);
 | 
						||
      if (_grid->on_resize_column(cid, xiev->v.column.new_col_width))
 | 
						||
        _columns_order = 1;
 | 
						||
      else
 | 
						||
        refused = true;  
 | 
						||
    }                           
 | 
						||
    break;  
 | 
						||
  case XIE_SELECT:                                
 | 
						||
    if (xiev->v.select.xi_obj->type == XIT_ROW) // Considero solo le righe
 | 
						||
    {                                         
 | 
						||
      if (xiev->v.select.selected)              // Sto selezionando
 | 
						||
      {
 | 
						||
        const long rec = row2rec(xiev->v.select.xi_obj->v.row_data.row);
 | 
						||
        if (try_to_select(rec))
 | 
						||
        { 
 | 
						||
          if (xiev->v.select.column == 0)
 | 
						||
          {  
 | 
						||
//            if (_read_only)                // Commentato 8/11/2013 altrimenti non funziona pi<70> collegamento a cg2
 | 
						||
//              refused = !select(rec);
 | 
						||
//            else
 | 
						||
            {
 | 
						||
              if (rec == _cur_rec) // Simulo intercettazione doppio click
 | 
						||
                _grid->on_record_button(rec);
 | 
						||
            }
 | 
						||
          }  
 | 
						||
          else
 | 
						||
          {  
 | 
						||
            if (_read_only && rec == _cur_rec)
 | 
						||
            {                                    
 | 
						||
              const short cid = col2cid(xiev->v.select.column);
 | 
						||
              _grid->on_dbl_cell(rec, cid);
 | 
						||
              refused = true;
 | 
						||
            }
 | 
						||
          }    
 | 
						||
          _cur_rec = rec;   // Assegno solo ora il record corrente
 | 
						||
        }  
 | 
						||
        else 
 | 
						||
          refused = true;
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case XIE_CELL_REQUEST:
 | 
						||
    {                        
 | 
						||
      const long& rec = xiev->v.cell_request.rec;       
 | 
						||
      if (rec >= 0 && rec < items())
 | 
						||
      {
 | 
						||
        TGrid_cell cell(xiev);
 | 
						||
        const short cid = col2cid(cell.get_column());
 | 
						||
        if (cid >= FIRST_FIELD)
 | 
						||
        {
 | 
						||
          _grid->cell_request(rec, cid, cell);
 | 
						||
        }  
 | 
						||
        else
 | 
						||
        {
 | 
						||
          if (cell.size() > 2)
 | 
						||
          {
 | 
						||
            cell.set(rec+1);
 | 
						||
            // Setto il colore del testo altrimenti verrebbe grigio:
 | 
						||
            // non uso la set_color perche' ignora NORMAL_COLOR
 | 
						||
            xiev->v.cell_request.color = NORMAL_COLOR;  
 | 
						||
          }  
 | 
						||
        }  
 | 
						||
      }
 | 
						||
      else
 | 
						||
        refused = true;       // Ogni tanto succede
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case XIE_ON_ROW:
 | 
						||
    { // Qui ci passa solo se non e' _read_only                 
 | 
						||
      const long rec = row2rec(xiev->v.xi_obj->v.row);
 | 
						||
      if (rec >= 0)
 | 
						||
      {
 | 
						||
        if (_grid->on_record(rec))
 | 
						||
          _cur_rec = rec;
 | 
						||
        else
 | 
						||
          refused = true;  
 | 
						||
      }  
 | 
						||
      else  
 | 
						||
      {
 | 
						||
        NFCHECK("You are entering an invalid row: %d", xiev->v.xi_obj->v.row);
 | 
						||
        refused = true;
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case XIE_OFF_ROW:
 | 
						||
    // Qui ci passa solo se non e' _read_only                 
 | 
						||
    if (_cur_rec >= 0 && _cur_rec < items())
 | 
						||
      refused = !_grid->off_record(_cur_rec);
 | 
						||
    break;
 | 
						||
  case XIE_ON_CELL:
 | 
						||
    break;  
 | 
						||
  case XIE_DBL_CELL:
 | 
						||
    {
 | 
						||
      const long rec = row2rec(xiev->v.xi_obj->v.cell.row);
 | 
						||
      if (try_to_select(rec))
 | 
						||
      {
 | 
						||
        const short cid = col2cid(xiev->v.xi_obj->v.cell.column);
 | 
						||
        _grid->on_dbl_cell(rec, cid);
 | 
						||
      }    
 | 
						||
    }  
 | 
						||
    break;   
 | 
						||
  case XIE_BUTTON:  
 | 
						||
    if (xiev->v.xi_obj->type == XIT_LIST)
 | 
						||
    {
 | 
						||
      _grid->on_grid_button();
 | 
						||
    }  
 | 
						||
    else
 | 
						||
    {
 | 
						||
      const XI_CELL_DATA& cell = xiev->v.xi_obj->v.cell;
 | 
						||
      const long rec = row2rec(cell.row);
 | 
						||
      if (try_to_select(rec))
 | 
						||
      {
 | 
						||
        const short cid = col2cid(cell.column);
 | 
						||
        _grid->on_cell_button(rec, cid);
 | 
						||
      }  
 | 
						||
      else
 | 
						||
        NFCHECK("You are clicking an invalid cell: %d", cell.row);
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  
 | 
						||
  return !refused;
 | 
						||
}
 | 
						||
 | 
						||
XI_OBJ* TGrid_control::find_column(short cid) const
 | 
						||
{
 | 
						||
  int num = 0;
 | 
						||
  XI_OBJ** column = xi_get_member_list(_obj, &num);
 | 
						||
  int i;
 | 
						||
  for (i = num-1; i >= 0; i--) 
 | 
						||
  {
 | 
						||
    if (column[i]->cid == cid)
 | 
						||
      break;
 | 
						||
  }         
 | 
						||
  return i >= 0 ? column[i] : NULL;
 | 
						||
}
 | 
						||
 | 
						||
XI_OBJ* TGrid_control::find_column(const char* head) const
 | 
						||
{
 | 
						||
  int num = 0;
 | 
						||
  XI_OBJ** column = xi_get_member_list(_obj, &num);
 | 
						||
  
 | 
						||
  TString256 text;
 | 
						||
  int i;
 | 
						||
  for (i = num-1; i >= 0; i--) 
 | 
						||
  { 
 | 
						||
    xi_get_text(column[i], text.get_buffer(), text.size());
 | 
						||
    if (text == head)
 | 
						||
      break;
 | 
						||
  }         
 | 
						||
  return i >= 0 ? column[i] : NULL;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_control::show_column(short cid, bool on)
 | 
						||
{   
 | 
						||
  XI_OBJ* column = find_column(cid);
 | 
						||
  if (column)
 | 
						||
  {
 | 
						||
/* Useless
 | 
						||
    dword attr = xi_get_attrib(column);
 | 
						||
    if (on) attr |= XI_ATR_VISIBLE;
 | 
						||
    else    attr &= ~XI_ATR_VISIBLE;
 | 
						||
    xi_set_attrib(column, attr);          // Set new attributes
 | 
						||
    update(-1);
 | 
						||
*/
 | 
						||
    if (!on)
 | 
						||
      xi_delete(column);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_control::set_columns_order(TToken_string* order)
 | 
						||
{                                 
 | 
						||
  XI_OBJ* itf = get_interface();
 | 
						||
  XI_OBJ* focus = xi_get_focus(itf);
 | 
						||
  xi_set_focus(itf);
 | 
						||
  
 | 
						||
  int num_cols;
 | 
						||
  XI_OBJ** column = xi_get_member_list(_obj, &num_cols);
 | 
						||
  
 | 
						||
  // Costante da sottrarre nella xi_column_set_pixel_width altrimenti la somma due volte!
 | 
						||
  const int offset = 2 * (int)xi_get_pref(XI_PREF_COLUMN_OFFSET);
 | 
						||
  const int fixed = xi_get_fixed_columns(_obj);
 | 
						||
  if (fixed > 1)
 | 
						||
    xi_set_fixed_columns(_obj, 1);
 | 
						||
  
 | 
						||
  if (order == NULL)
 | 
						||
  {
 | 
						||
    for (int index = 1; index < num_cols; index++)
 | 
						||
    {                                
 | 
						||
      const short cid = FIRST_FIELD + 1000 + index - 1;
 | 
						||
      XI_OBJ* col = find_column(cid);
 | 
						||
      if (col)
 | 
						||
      {
 | 
						||
        xi_move_column(col, index); 
 | 
						||
        RCT rct; xi_get_rect(col, (XinRect*)&rct);
 | 
						||
        if (_default_width[index] != rct.right - rct.left)
 | 
						||
          xi_column_set_pixel_width(col, _default_width[index]-offset);
 | 
						||
      }    
 | 
						||
    }  
 | 
						||
    _columns_order = 0x3;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {              
 | 
						||
    TToken_string col(8, ',');
 | 
						||
    int pos = 0;
 | 
						||
    for (col = order->get(0); !col.blank(); col = order->get(), pos++)
 | 
						||
    {
 | 
						||
      const char* head = esc(col.get(0));
 | 
						||
      const int width = col.get_int();
 | 
						||
      XI_OBJ* column = find_column(head);
 | 
						||
      if (column)                        // Controlla che esista ancora
 | 
						||
      {             
 | 
						||
        if (pos > 0 && pos < num_cols)
 | 
						||
          xi_move_column(column, pos);   // Sposta la colonna se possibile
 | 
						||
        if (width > XI_FU_MULTIPLE)      // Se ha una larghezza valida
 | 
						||
          xi_column_set_pixel_width(column, width - offset);
 | 
						||
      }
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (fixed > 1)
 | 
						||
    xi_set_fixed_columns(_obj, fixed);
 | 
						||
  
 | 
						||
  if (focus)
 | 
						||
    xi_set_focus(focus);
 | 
						||
}      
 | 
						||
 | 
						||
HIDDEN TFilename& field2parag(const TMask_field& f, TFilename& name)
 | 
						||
{ 
 | 
						||
  const TMask& m = f.mask();
 | 
						||
  name = m.source_file();      
 | 
						||
  name.ext("");                // Nome della maschera senza estensione
 | 
						||
  const int index = m.number();
 | 
						||
  CHECKD(index >= 0 && index <= 8, "Bad mask index:", index);
 | 
						||
  if (index > 0)          // Aggiunge l'eventuale numero di sotto-maschera
 | 
						||
    name << '(' << index << ')';
 | 
						||
  return name;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_control::load_columns_order()
 | 
						||
{
 | 
						||
  TFilename parag; field2parag(*_grid, parag);
 | 
						||
  TConfig config(CONFIG_USER, parag);
 | 
						||
  TToken_string order = config.get("Browse", NULL, id());
 | 
						||
  if (order.empty_items())
 | 
						||
    config.remove("Browse", id());
 | 
						||
  else
 | 
						||
    set_columns_order(&order);
 | 
						||
  _columns_order = 0;  
 | 
						||
}    
 | 
						||
 | 
						||
void TGrid_control::save_columns_order() const
 | 
						||
{
 | 
						||
  if (_columns_order)
 | 
						||
  {
 | 
						||
    TFilename parag; field2parag(*_grid, parag);
 | 
						||
    TConfig config(CONFIG_USER, parag);   // Apre il file di configurazione
 | 
						||
 | 
						||
    TToken_string order(127);             // Nuovo ordine delle colonne
 | 
						||
    if (_columns_order == 1)              // Se vale 3 devo solo resettare
 | 
						||
    {
 | 
						||
      int num;
 | 
						||
      XI_OBJ** column = xi_get_member_list(_obj, &num);
 | 
						||
      TString80 head;
 | 
						||
      for (int i = 0; i < num; i++)       // Scorre tutte le colonne
 | 
						||
      {             
 | 
						||
        xi_get_text(column[i], head.get_buffer(), head.size());
 | 
						||
        const int acapo = head.find('\n');
 | 
						||
        if (acapo > 0)
 | 
						||
        {
 | 
						||
          head[acapo] = '\\';
 | 
						||
          head.insert("n", acapo+1);
 | 
						||
        }
 | 
						||
        order.add(head);
 | 
						||
        RCT rct; xi_get_rect(column[i], (XinRect*)&rct);
 | 
						||
        order << ',' << rct.right - rct.left;
 | 
						||
      }
 | 
						||
      config.set("Browse", order, NULL, true, id());
 | 
						||
    }  
 | 
						||
    else
 | 
						||
      config.remove("Browse", id());
 | 
						||
  }  
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TGrid_cell
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TGrid_cell::TGrid_cell(XI_EVENT* xiev) 
 | 
						||
          : TFixed_string(xiev->v.cell_request.s, xiev->v.cell_request.len), 
 | 
						||
            _xiev(xiev) 
 | 
						||
{ }
 | 
						||
 | 
						||
 | 
						||
// Setta il testo di una cella (Mai piu' testo troppo lungo!)
 | 
						||
// Se c'e' gia' un'icona la elimina
 | 
						||
TString& TGrid_cell::set(const char* txt)
 | 
						||
{ 
 | 
						||
  strncpy(txt, size());
 | 
						||
  if (not_empty())
 | 
						||
  {
 | 
						||
    int& icon = _xiev->v.cell_request.icon_rid;
 | 
						||
    if (icon)
 | 
						||
      icon = 0;
 | 
						||
  }    
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
TString& TGrid_cell::set(long num)
 | 
						||
{
 | 
						||
  char buff[16];
 | 
						||
  sprintf(buff, "%ld", num);
 | 
						||
  return set(buff);
 | 
						||
}
 | 
						||
 | 
						||
// Setta l'icona di una cella
 | 
						||
// Se c'e' gia' un testo lo elimina
 | 
						||
void TGrid_cell::set_icon(int id)
 | 
						||
{
 | 
						||
  _xiev->v.cell_request.icon_rid = id;
 | 
						||
  if (id)
 | 
						||
    _xiev->v.cell_request.s[0] = '\0';
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_cell::show_button(bool on)
 | 
						||
{                         
 | 
						||
  _xiev->v.cell_request.button = on;
 | 
						||
  _xiev->v.cell_request.button_on_focus = on;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_cell::set_back_color(COLOR col)
 | 
						||
{                                        
 | 
						||
  if (col != NORMAL_BACK_COLOR)
 | 
						||
    _xiev->v.cell_request.back_color = col;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_cell::set_fore_color(COLOR col)
 | 
						||
{
 | 
						||
  if (col != NORMAL_COLOR)
 | 
						||
    _xiev->v.cell_request.color = col;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_cell::set_colors(COLOR back, COLOR fore)
 | 
						||
{
 | 
						||
  if (back != NORMAL_BACK_COLOR)
 | 
						||
    _xiev->v.cell_request.back_color = back;
 | 
						||
  if (fore != NORMAL_COLOR)
 | 
						||
    _xiev->v.cell_request.color = fore;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TGrid_field
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TGrid_field::TGrid_field(TMask* m) 
 | 
						||
           : TOperable_field(m) 
 | 
						||
{ }      
 | 
						||
 | 
						||
word TGrid_field::class_id() const
 | 
						||
{
 | 
						||
  return CLASS_GRID_FIELD;
 | 
						||
}  
 | 
						||
 | 
						||
void TGrid_field::update(long n) 
 | 
						||
{ grid().update(n); }
 | 
						||
 | 
						||
void TGrid_field::parse_head(TScanner& scanner)
 | 
						||
{
 | 
						||
  _ctl_data._width  = scanner.integer();
 | 
						||
  _ctl_data._height = scanner.integer();
 | 
						||
  if (_ctl_data._height == 0) 
 | 
						||
    _ctl_data._height = -1;
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_field::create(WINDOW parent)
 | 
						||
{ 
 | 
						||
  _ctl = new TGrid_control(parent, dlg(), 
 | 
						||
                           _ctl_data._x, _ctl_data._y, 
 | 
						||
                           _ctl_data._width, _ctl_data._height, 
 | 
						||
                           _ctl_data._flags, _ctl_data._park,
 | 
						||
                           this);
 | 
						||
  grid().load_columns_order();
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_field::parse_item(TScanner& scanner)
 | 
						||
{
 | 
						||
  if (scanner.key() == "IT")
 | 
						||
  {
 | 
						||
    _ctl_data._park.add(scanner.string());
 | 
						||
    return true;
 | 
						||
  }
 | 
						||
  return TMask_field::parse_item(scanner);
 | 
						||
}   
 | 
						||
 | 
						||
 | 
						||
bool TGrid_field::handler(XI_EVENT* xiev)
 | 
						||
{                    
 | 
						||
  return false;
 | 
						||
}
 | 
						||
 | 
						||
long TGrid_field::items() const
 | 
						||
{
 | 
						||
  return 100000L;
 | 
						||
}
 | 
						||
 | 
						||
int TGrid_field::visible_rows() const
 | 
						||
{
 | 
						||
  return grid().visible_rows();
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_field::cell_request(long rec, short id, TGrid_cell& cell)
 | 
						||
{
 | 
						||
  cell.set("Cell");
 | 
						||
}
 | 
						||
 | 
						||
long TGrid_field::selected() const
 | 
						||
{ return grid().selected(); }
 | 
						||
 | 
						||
bool TGrid_field::select(long rec)
 | 
						||
{ return grid().select(rec); }
 | 
						||
 | 
						||
void TGrid_field::reset_columns_order()
 | 
						||
{ 
 | 
						||
  grid().reset_columns_order();
 | 
						||
}
 | 
						||
 | 
						||
void TGrid_field::save_columns_order() const 
 | 
						||
{
 | 
						||
  grid().save_columns_order();
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Da qui in poi e' tutta roba specializzata del programma
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Maschera per colori
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TColor_mask : public TSelect_color_mask
 | 
						||
{
 | 
						||
public:
 | 
						||
  void get_colors(COLOR& mb, COLOR& mf, COLOR& cb, COLOR& cf);
 | 
						||
  TColor_mask();
 | 
						||
};
 | 
						||
 | 
						||
void TColor_mask::get_colors(COLOR& mb, COLOR& mf, COLOR& cb, COLOR& cf)
 | 
						||
{
 | 
						||
  get_color("M", mb, mf);
 | 
						||
  get_color("C", cb, cf);
 | 
						||
}
 | 
						||
 | 
						||
TColor_mask::TColor_mask() : TSelect_color_mask("cg3600b")
 | 
						||
{
 | 
						||
  add_color_def("M", TR("Riga mastrino"), REQUIRED_BACK_COLOR, FOCUS_COLOR);
 | 
						||
  add_color_def("C", TR("Riga contropartita"), NORMAL_BACK_COLOR, NORMAL_COLOR);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TMastrini_grid
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TMastrini_grid : public TGrid_field
 | 
						||
{                      
 | 
						||
  TMastrino _mastrino;    
 | 
						||
  
 | 
						||
  TDecoder _causali;
 | 
						||
  TEsercizi_contabili _esercizi;
 | 
						||
  
 | 
						||
  TColor_mask _colmsk;
 | 
						||
  COLOR _mas_back, _mas_fore;
 | 
						||
  COLOR _con_back, _con_fore;
 | 
						||
  bool _primanoting, _contsep;
 | 
						||
  
 | 
						||
protected: // TGrid_field  
 | 
						||
  virtual bool on_record(long rec);
 | 
						||
  virtual void on_grid_button();
 | 
						||
  virtual bool on_resize_column(short id, int new_size);
 | 
						||
                
 | 
						||
  void update_mask() const;
 | 
						||
 | 
						||
public:                                                   
 | 
						||
  virtual void cell_request(long rec, short id, TGrid_cell& cell);
 | 
						||
  virtual void on_dbl_cell(long rec, short id);
 | 
						||
  virtual void on_record_button(long rec);
 | 
						||
  virtual long items() const { return _mastrino.items(); }
 | 
						||
 | 
						||
  void destroy();
 | 
						||
  void read(const TBill& conto, 
 | 
						||
            int annoes, const TDate& dd, const TDate& ad,
 | 
						||
            const TString& dc, const TString& ac, bool provv);
 | 
						||
  void reread();          
 | 
						||
            
 | 
						||
  TMastrino& mastrino() { return _mastrino; }          
 | 
						||
 | 
						||
  void save_colors();
 | 
						||
  void load_colors();
 | 
						||
  void set_colors();
 | 
						||
  void set_contsep(bool cs) { _contsep = cs; }
 | 
						||
  
 | 
						||
  TMastrini_grid(TMask* m);
 | 
						||
  virtual ~TMastrini_grid() { }
 | 
						||
};
 | 
						||
 | 
						||
TMastrini_grid::TMastrini_grid(TMask* m)
 | 
						||
              : TGrid_field(m), _causali(LF_CAUSALI, CAU_DESCR), _primanoting(false), _contsep(false)
 | 
						||
{
 | 
						||
  load_colors();
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_grid::destroy() 
 | 
						||
{ 
 | 
						||
  _mastrino.destroy();    
 | 
						||
  grid().select(-1);
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN const char* real2string(const real& r)
 | 
						||
{
 | 
						||
  const TCurrency cur(r);
 | 
						||
  return cur.string(true);
 | 
						||
}
 | 
						||
 | 
						||
HIDDEN void set_imp(TMask_field& f, const TImporto& imp)
 | 
						||
{
 | 
						||
  if (!imp.is_zero())
 | 
						||
  {
 | 
						||
    TString80 str;
 | 
						||
    str.format("%s %c", real2string(imp.valore()), imp.sezione());
 | 
						||
    f.set(str);
 | 
						||
  }  
 | 
						||
  else
 | 
						||
    f.reset();
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_grid::cell_request(long rec, short id, TGrid_cell& cell)
 | 
						||
{     
 | 
						||
  if (rec < 0) // testate
 | 
						||
  {
 | 
						||
    XI_OBJ* col = grid().find_column(short(1000+id%1000));
 | 
						||
    if (col != NULL)
 | 
						||
    {
 | 
						||
      TString256 str;
 | 
						||
      xi_get_text(col, str.get_buffer(), str.size());
 | 
						||
      cell = str;
 | 
						||
 | 
						||
    }
 | 
						||
    return;
 | 
						||
  }
 | 
						||
 | 
						||
  const TRiga_mastrino& riga = _mastrino[rec];
 | 
						||
  
 | 
						||
  switch (id)
 | 
						||
  {
 | 
						||
  case 101:
 | 
						||
    if (riga.tipo() == riga_mastrino)
 | 
						||
    {
 | 
						||
      const TRectype& mov = _mastrino.testata(rec);
 | 
						||
      cell = riga.data().string();
 | 
						||
      cell << ' ' << mov.get(MOV_DATADOC);
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case 102:
 | 
						||
    if (riga.tipo() == riga_mastrino)
 | 
						||
    { 
 | 
						||
      const TRectype& mov = _mastrino.testata(rec);
 | 
						||
      const int anno = _esercizi.date2esc(riga.data());
 | 
						||
      const int eser = mov.get_int(MOV_ANNOES);
 | 
						||
      TString8 str;
 | 
						||
      if (anno != eser) 
 | 
						||
        str = "C";  // Di competenza vecchia
 | 
						||
      if (mov.get(MOV_PROVVIS).not_empty())
 | 
						||
      {
 | 
						||
        if (str.not_empty())
 | 
						||
          str << '/';
 | 
						||
        str << 'P';
 | 
						||
      }
 | 
						||
      cell = str;
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case 103:
 | 
						||
    if (riga.tipo() == riga_mastrino)
 | 
						||
    {
 | 
						||
      const TRectype& mov = _mastrino.testata(rec);
 | 
						||
      cell.set(_causali.decode(mov.get(MOV_CODCAUS)));
 | 
						||
    }  
 | 
						||
    else
 | 
						||
    {
 | 
						||
      const TRectype& rmov = _mastrino.riga(rec);
 | 
						||
      cell.format("%03d.%03d.%06ld",
 | 
						||
                  rmov.get_int(RMV_GRUPPO), 
 | 
						||
                  rmov.get_int(RMV_CONTO),
 | 
						||
                  rmov.get_long(RMV_SOTTOCONTO));
 | 
						||
    }
 | 
						||
    break;      
 | 
						||
  case 104: // Descrizione
 | 
						||
    {
 | 
						||
      const TRectype& rmov = _mastrino.riga(rec);
 | 
						||
      const TRectype& mov = _mastrino.testata(rec);
 | 
						||
      TString descr = rmov.get(RMV_DESCR);
 | 
						||
      if (riga.tipo() == riga_mastrino)
 | 
						||
      {                                  
 | 
						||
        if (descr.empty())
 | 
						||
        {
 | 
						||
          const TRectype& mov = _mastrino.testata(rec);
 | 
						||
          descr = mov.get(MOV_DESCR);
 | 
						||
          if (descr.empty())
 | 
						||
          {
 | 
						||
            TBill uncle(rmov,true);
 | 
						||
            descr = uncle.descrizione();
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }  
 | 
						||
      else
 | 
						||
      {
 | 
						||
        // Bug 0001748: ignora descrizioni generate da contabilizzazione
 | 
						||
        if (descr.empty() || descr == _mastrino.conto().descrizione()) 
 | 
						||
        {
 | 
						||
          const TBill conto(rmov);
 | 
						||
          descr =  conto.descrizione();
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (_contsep)
 | 
						||
      {
 | 
						||
        const TString16 cs = mov.get(MOV_CONTSEP);
 | 
						||
        if (cs.full())
 | 
						||
          descr << "\n" << cache().get("&NPENT", cs, "S0");
 | 
						||
      }
 | 
						||
      cell.set(descr);
 | 
						||
    }
 | 
						||
    break;  
 | 
						||
  case 105: // Dare
 | 
						||
    {
 | 
						||
      const TRectype& rmov = _mastrino.riga(rec);
 | 
						||
      const char sez = rmov.get_char(RMV_SEZIONE);   
 | 
						||
      if (sez == 'D')
 | 
						||
        cell = real2string(rmov.get_real(RMV_IMPORTO));
 | 
						||
    }    
 | 
						||
    break;
 | 
						||
  case 106: // Avere
 | 
						||
    {
 | 
						||
      const TRectype& rmov = _mastrino.riga(rec);
 | 
						||
      const char sez = rmov.get_char(RMV_SEZIONE);
 | 
						||
      if (sez == 'A')
 | 
						||
        cell = real2string(rmov.get_real(RMV_IMPORTO));
 | 
						||
    }    
 | 
						||
    break;
 | 
						||
  case 107:
 | 
						||
    if (riga.tipo() == riga_mastrino)
 | 
						||
    {
 | 
						||
      const TRectype& mov = _mastrino.testata(rec);
 | 
						||
      cell = mov.get(MOV_NUMDOC); cell.left_just(7);
 | 
						||
      cell << ' ' << mov.get(MOV_PROTIVA);
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case 108:
 | 
						||
    { 
 | 
						||
      const TRectype& rmov = _mastrino.riga(rec);
 | 
						||
      cell = real2string(rmov.get_real(RMV_IMPORTO));
 | 
						||
      cell << ' ' << rmov.get(RMV_SEZIONE);
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case 109:
 | 
						||
    if (riga.tipo() == riga_mastrino)
 | 
						||
    {
 | 
						||
      const long next_row = _mastrino.succ(rec, riga_mastrino);
 | 
						||
      bool stampa = next_row >= _mastrino.items();
 | 
						||
      if (!stampa)
 | 
						||
      {
 | 
						||
        const TDate& data = _mastrino[next_row].data();
 | 
						||
        stampa = riga.data() != data;
 | 
						||
      }
 | 
						||
      if (stampa)
 | 
						||
      {
 | 
						||
        TImporto imp = riga.saldo();
 | 
						||
        imp += _mastrino.saldo_iniziale();
 | 
						||
        imp.normalize();
 | 
						||
        cell = real2string(imp.valore());
 | 
						||
        cell << ' ' << imp.sezione();
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case 110:
 | 
						||
    if (riga.tipo() == riga_mastrino)
 | 
						||
    {
 | 
						||
      const TRectype& mov = _mastrino.testata(rec);
 | 
						||
      TLocalisamfile movana(LF_MOVANA);
 | 
						||
      movana.setkey(3);
 | 
						||
      movana.put(MOVANA_NUMREGCG, mov.get(MOV_NUMREG));
 | 
						||
      if (movana.read() == NOERR)
 | 
						||
      {
 | 
						||
        const TRectype& rmov = _mastrino.riga(rec);
 | 
						||
        const TBill bill(rmov);
 | 
						||
        const TString16 codconto = bill.string(0x8);  // GGGCCCSSSSSS 
 | 
						||
        const TRecord_array rmovana(movana.get(MOVANA_NUMREG), LF_RMOVANA);
 | 
						||
        const int last_rmovana = rmovana.last_row();
 | 
						||
        const real target = rmov.get(RMV_IMPORTO);
 | 
						||
 | 
						||
        TBit_array hits;
 | 
						||
 | 
						||
        if (hits.first_one() < 0)
 | 
						||
        {
 | 
						||
          // Controllo se c'<27> corrispondenza biunivoca tra le righe di CG e CA
 | 
						||
          const int nriga = rmov.get_int(RMV_NUMRIG);
 | 
						||
          if (nriga <= last_rmovana && rmovana.exist(nriga))
 | 
						||
          {
 | 
						||
            const TRectype& r = rmovana.row(nriga);
 | 
						||
            if (r.get(RMOVANA_CODCONTO) == codconto && r.get_real(RMOVANA_IMPORTO) == target)
 | 
						||
              hits.set(nriga);
 | 
						||
          }
 | 
						||
        }
 | 
						||
 | 
						||
        if (hits.first_one() < 0)
 | 
						||
        {
 | 
						||
          // Controllo se esiste una riga che corrisponda per importo e conto analitico/contabile
 | 
						||
          for (int i = rmovana.first_row(); i > 0 && i <= last_rmovana; i = rmovana.succ_row(i))
 | 
						||
          {
 | 
						||
            const TRectype& r = rmovana.row(i);
 | 
						||
            if (r.get(RMOVANA_CODCONTO) == codconto)
 | 
						||
            {
 | 
						||
              const real imp = r.get(RMOVANA_IMPORTO);
 | 
						||
              if (imp == target)
 | 
						||
              {
 | 
						||
                hits.set(i);
 | 
						||
                break;
 | 
						||
              }
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
  
 | 
						||
        if (hits.first_one() < 0)
 | 
						||
        {
 | 
						||
          // Faccio la somma delle righe che corrispondono per conto analitico/contabile
 | 
						||
          real total_hits;
 | 
						||
          for (int i = rmovana.first_row(); i > 0 && i <= last_rmovana; i = rmovana.succ_row(i))
 | 
						||
          {
 | 
						||
            const TRectype& r = rmovana.row(i);
 | 
						||
            if (r.get(RMOVANA_CODCONTO) == codconto)
 | 
						||
            {
 | 
						||
              const real imp = r.get(RMOVANA_IMPORTO);
 | 
						||
              hits.set(i);
 | 
						||
              total_hits += imp;
 | 
						||
              if (total_hits >= target)
 | 
						||
                break;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
 | 
						||
        TString cms;
 | 
						||
        for (int h = hits.first_one(); h >= 0 && h <= last_rmovana; h++) if (hits[h])
 | 
						||
        {
 | 
						||
          const TRectype& r = rmovana.row(h);
 | 
						||
          TString80 cod = r.get(RMOVANA_CODCMS);
 | 
						||
          if (cod.starts_with("00000"))
 | 
						||
          {
 | 
						||
            int i = 0;
 | 
						||
            for (i = 5; cod[i] == '0'; i++);
 | 
						||
            cod.ltrim(i);
 | 
						||
          }
 | 
						||
          if (cms.not_empty()) 
 | 
						||
            cms << ' ';
 | 
						||
          cms << cod;
 | 
						||
          if (cms.len() >= cell.size())
 | 
						||
            break;
 | 
						||
        }
 | 
						||
        if (cms.len() >= cell.size())
 | 
						||
          cms.cut(cell.size()-1);
 | 
						||
        cell = cms;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (riga.tipo() == riga_mastrino)
 | 
						||
    cell.set_colors(_mas_back, _mas_fore);
 | 
						||
  else
 | 
						||
    cell.set_colors(_con_back, _con_fore);
 | 
						||
}
 | 
						||
 | 
						||
bool TMastrini_grid::on_record(long rec)
 | 
						||
{
 | 
						||
  if (_mastrino[rec].tipo() != riga_mastrino)
 | 
						||
    rec = _mastrino.pred(rec, riga_mastrino);
 | 
						||
 | 
						||
  TRiga_mastrino& riga = _mastrino[rec];
 | 
						||
  TMask& gm = mask();
 | 
						||
  set_imp(gm.field(F_TOTRIG_SAL), riga.saldo());
 | 
						||
  gm.set(F_TOTRIG_DAR, riga.dare());
 | 
						||
  gm.set(F_TOTRIG_AVE, riga.avere());
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_grid::on_dbl_cell(long rec, short id)
 | 
						||
{
 | 
						||
  if (rec >= 0 && rec < items())
 | 
						||
  {
 | 
						||
    if (_mastrino.expandable(rec)) 
 | 
						||
      _mastrino.expand(rec);
 | 
						||
    else
 | 
						||
      _mastrino.collapse(rec);
 | 
						||
    update();  
 | 
						||
  }
 | 
						||
} 
 | 
						||
 | 
						||
void TMastrini_grid::on_grid_button()
 | 
						||
{                           
 | 
						||
  const long total = _mastrino.items();                      
 | 
						||
  if (total > 0)
 | 
						||
  {
 | 
						||
    TProgind* pi = NULL;
 | 
						||
      
 | 
						||
    if (total > 50)
 | 
						||
      pi = new TProgind(total, TR("Aggiornamento contropartite ..."), false, true, 48);
 | 
						||
    else
 | 
						||
      begin_wait();  
 | 
						||
    
 | 
						||
    // Cerca l'ultima contropartita
 | 
						||
    const long last_con = _mastrino.last(riga_contropartita);
 | 
						||
    // Se non esistono contropartite devo espandere le righe
 | 
						||
    const bool expand = last_con < 0;
 | 
						||
    
 | 
						||
#ifdef DBG
 | 
						||
    const clock_t clock_start = clock();
 | 
						||
#endif    
 | 
						||
    
 | 
						||
    if (expand)
 | 
						||
    {                         
 | 
						||
      long step = 0;
 | 
						||
      for (long n = _mastrino.first(riga_mastrino); 
 | 
						||
           n < _mastrino.items(); n = _mastrino.succ(n, riga_mastrino))
 | 
						||
      {
 | 
						||
        if (_mastrino.expandable(n))
 | 
						||
          _mastrino.expand(n);
 | 
						||
        if (pi)
 | 
						||
        {
 | 
						||
          pi->setstatus(++step); 
 | 
						||
#ifdef DBG               
 | 
						||
          if ((step & 0x7F) == 0)
 | 
						||
          {
 | 
						||
            const double sec = (clock() - clock_start) / CLOCKS_PER_SEC;
 | 
						||
            if (sec > 0.0)
 | 
						||
            {
 | 
						||
              TString80 msg;
 | 
						||
              msg.format(FR("%ld records at %ld rec/sec"), step, long(step/sec));
 | 
						||
              pi->set_text(msg);
 | 
						||
            }  
 | 
						||
          }
 | 
						||
#endif          
 | 
						||
        }  
 | 
						||
      }       
 | 
						||
    }      
 | 
						||
    else
 | 
						||
    {                                             
 | 
						||
      for (long n = last_con; n > 0; n = _mastrino.pred(n, riga_contropartita))
 | 
						||
      {
 | 
						||
        _mastrino.collapse(n);
 | 
						||
        if (pi)
 | 
						||
          pi->setstatus(total - n + 1);
 | 
						||
      }    
 | 
						||
    }
 | 
						||
      
 | 
						||
    if (pi)
 | 
						||
      delete pi;
 | 
						||
    else
 | 
						||
      end_wait();  
 | 
						||
 | 
						||
    update();
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_grid::on_record_button(long rec)
 | 
						||
{
 | 
						||
  if (!_primanoting)
 | 
						||
  {
 | 
						||
    _primanoting = true;
 | 
						||
    const TRectype& testata = _mastrino.testata(rec);
 | 
						||
    testata.edit();
 | 
						||
    if (yesno_box(TR("Si desidera aggiornare il mastrino?")))
 | 
						||
      reread();
 | 
						||
    _primanoting = false;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// Posso ridimensionare solo le descrizioni, le altre devono rimanere fisse per
 | 
						||
// non perdere la formattazione su due righe
 | 
						||
bool TMastrini_grid::on_resize_column(short cid, int new_size) 
 | 
						||
{ 
 | 
						||
  return cid == 103 || cid == 104;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
void TMastrini_grid::read(const TBill& conto, 
 | 
						||
                          int annoes, const TDate& dd, const TDate& ad,
 | 
						||
                          const TString& dc, const TString& ac, bool provv)
 | 
						||
{
 | 
						||
  destroy();
 | 
						||
  _mastrino.read(conto, annoes, dd, ad, dc, ac, provv);
 | 
						||
  update();    
 | 
						||
  update_mask();
 | 
						||
}                          
 | 
						||
 | 
						||
void TMastrini_grid::reread()
 | 
						||
{
 | 
						||
  destroy();
 | 
						||
  _mastrino.reread();
 | 
						||
  update();
 | 
						||
  update_mask();
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_grid::update_mask() const
 | 
						||
{
 | 
						||
  TMask& gm = mask();    
 | 
						||
  
 | 
						||
  gm.set(F_ESERCIZIO, _mastrino.esercizio());
 | 
						||
  gm.set(F_DADATA, _mastrino.inizio_periodo());
 | 
						||
  gm.set(F_ADATA, _mastrino.fine_periodo());
 | 
						||
  
 | 
						||
  set_imp(gm.field(F_TOTPRO_SAL), _mastrino.saldo_iniziale());
 | 
						||
  gm.set(F_TOTPRO_DAR, _mastrino.progressivo_dare_iniziale());
 | 
						||
  gm.set(F_TOTPRO_AVE, _mastrino.progressivo_avere_iniziale());
 | 
						||
  
 | 
						||
  gm.reset(F_TOTRIG_SAL);
 | 
						||
  gm.reset(F_TOTRIG_DAR);
 | 
						||
  gm.reset(F_TOTRIG_AVE);
 | 
						||
 | 
						||
  set_imp(gm.field(F_TOTPER_SAL), _mastrino.saldo_periodo());
 | 
						||
  gm.set(F_TOTPER_DAR, _mastrino.progressivo_dare_periodo());
 | 
						||
  gm.set(F_TOTPER_AVE, _mastrino.progressivo_avere_periodo());
 | 
						||
 | 
						||
  set_imp(gm.field(F_TOTATT_SAL), _mastrino.saldo_finale());
 | 
						||
  gm.set(F_TOTATT_DAR, _mastrino.progressivo_dare_finale());
 | 
						||
  gm.set(F_TOTATT_AVE, _mastrino.progressivo_avere_finale());
 | 
						||
  
 | 
						||
  const bool can_link = main_app().argc() <= 2; // NON sono stato chiamato dalla prima nota
 | 
						||
  gm.enable(DLG_LINK, can_link && _mastrino.items() > 0);
 | 
						||
  gm.enable(DLG_NEWREC, can_link);
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_grid::load_colors()
 | 
						||
{
 | 
						||
  _colmsk.get_colors(_mas_back, _mas_fore, _con_back, _con_fore);
 | 
						||
}              
 | 
						||
 | 
						||
void TMastrini_grid::set_colors()
 | 
						||
{
 | 
						||
  if (_colmsk.run() == K_ENTER)
 | 
						||
    load_colors();
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TMastrino_set
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TMastrino_set : public TRecordset
 | 
						||
{
 | 
						||
  TMastrini_grid& _grid;
 | 
						||
  long _curr;
 | 
						||
  TArray _info;
 | 
						||
 | 
						||
protected:
 | 
						||
  void add_field(TFieldtypes t, short id, int width, const char* name = NULL);
 | 
						||
  long cell_request(long rec, short column, TString& str) const;
 | 
						||
  const TString& query_text() const { return EMPTY_STRING; }
 | 
						||
 | 
						||
public:
 | 
						||
  virtual TRecnotype items() const { return _grid.items(); }
 | 
						||
  virtual unsigned int columns() const { return _info.items(); }
 | 
						||
  virtual const TRecordset_column_info& column_info(unsigned int column) const;
 | 
						||
  virtual bool move_to(TRecnotype n);
 | 
						||
  virtual TRecnotype current_row() const { return _curr; }
 | 
						||
  virtual void requery() {}
 | 
						||
  virtual const TVariant& get(unsigned int column) const;
 | 
						||
 | 
						||
  TMastrino_set(TMastrini_grid& g);
 | 
						||
};
 | 
						||
 | 
						||
const TRecordset_column_info& TMastrino_set::column_info(unsigned int column) const 
 | 
						||
{ 
 | 
						||
  return (const TRecordset_column_info&)_info[column];
 | 
						||
}
 | 
						||
 | 
						||
bool TMastrino_set::move_to(TRecnotype n)
 | 
						||
{
 | 
						||
  const bool ok = n >= 0 && n < items();
 | 
						||
  _curr = n;
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
long TMastrino_set::cell_request(long rec, short column, TString& str) const
 | 
						||
{
 | 
						||
  XI_EVENT xiev; memset(&xiev, 0, sizeof(xiev));
 | 
						||
  xiev.type = XIE_CELL_REQUEST;
 | 
						||
  xiev.v.cell_request.s   = str.get_buffer();
 | 
						||
  xiev.v.cell_request.len = str.size();
 | 
						||
  TGrid_cell cell(&xiev);
 | 
						||
  _grid.cell_request(rec, column, cell);
 | 
						||
  return xiev.v.cell_request.attrib;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
const TVariant& TMastrino_set::get(unsigned int column) const
 | 
						||
{
 | 
						||
  if (_curr >= 0 && _curr < items() && column >= 0 && column < columns())
 | 
						||
  { 
 | 
						||
    const TRecordset_column_info& info = column_info(column);
 | 
						||
 | 
						||
    TToken_string str;
 | 
						||
    cell_request(_curr, abs(info._pos), str);
 | 
						||
    if (str.full())
 | 
						||
    {
 | 
						||
      //decide se il campo appartiene ad una sottocella (es. numdoc / prot)
 | 
						||
      bool divide = info._pos < 0;  //<2F> la prima parte di una sottocella
 | 
						||
      if (!divide && column < columns()-1)
 | 
						||
        divide = column_info(column+1)._pos < 0;  //<2F> la seconda parte di una sottocella
 | 
						||
      //se deve splittare cerca lo spazio come carattere di separazione tra le sottocelle
 | 
						||
      if (divide)
 | 
						||
      {
 | 
						||
        const int cr = str.find(' ');
 | 
						||
        if (cr >= 0) 
 | 
						||
        {
 | 
						||
          if (info._pos > 0)
 | 
						||
            str.cut(cr);
 | 
						||
          else
 | 
						||
            str.ltrim(cr);
 | 
						||
          str.trim();
 | 
						||
        }
 | 
						||
      }
 | 
						||
 | 
						||
      TVariant& tmp = get_tmp_var();
 | 
						||
      switch (info._type)
 | 
						||
      {
 | 
						||
      case _realfld:
 | 
						||
        tmp = real(real::ita2eng(str));
 | 
						||
        break;
 | 
						||
      case _longfld:
 | 
						||
        tmp = atol(str);
 | 
						||
        break;
 | 
						||
      case _datefld:
 | 
						||
        tmp = TDate(str);
 | 
						||
        break;
 | 
						||
      default:
 | 
						||
        if (info._width == 1) 
 | 
						||
          tmp = str.right(1);
 | 
						||
        else
 | 
						||
          tmp = str;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
      return tmp;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return NULL_VARIANT;
 | 
						||
}
 | 
						||
 | 
						||
void TMastrino_set::add_field(TFieldtypes tipo, short id, int width, const char* name)
 | 
						||
{
 | 
						||
  TRecordset_column_info* i = new TRecordset_column_info;
 | 
						||
 | 
						||
  TString& n = i->_name;
 | 
						||
 | 
						||
  if (name && *name)
 | 
						||
    n = name;
 | 
						||
  else
 | 
						||
  {
 | 
						||
    cell_request(-1, abs(id), n);
 | 
						||
    const int cr = n.find('\n');
 | 
						||
    if (cr > 0)
 | 
						||
    {
 | 
						||
      if (id > 0)
 | 
						||
        n.cut(cr);
 | 
						||
      else
 | 
						||
        n.ltrim(cr+1);
 | 
						||
      n.trim();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  
 | 
						||
  i->_type  = tipo;
 | 
						||
  i->_pos   = id;
 | 
						||
  i->_width = width;
 | 
						||
 | 
						||
  _info.add(i);
 | 
						||
}
 | 
						||
 | 
						||
TMastrino_set::TMastrino_set(TMastrini_grid& g) 
 | 
						||
             : _grid(g), _curr(-1) 
 | 
						||
{ 
 | 
						||
  _grid.mastrino().collapse(-1);// Nascondo tutte le righe di contropartita
 | 
						||
 | 
						||
  add_field(_datefld, 101, 10); // Data reg
 | 
						||
  add_field(_datefld,-101, 10); // Data comp 
 | 
						||
  add_field(_alfafld, 102,  1); // Movimento di competenza?
 | 
						||
  add_field(_alfafld, 103, 25); // Causale
 | 
						||
  add_field(_alfafld, 104, 50); // Descrizione
 | 
						||
  add_field(_realfld, 105, 13); // Dare
 | 
						||
  add_field(_realfld, 106, 13); // Avere
 | 
						||
  add_field(_alfafld, 107,  7); // Num doc
 | 
						||
  add_field(_longfld,-107,  7); // Num prot
 | 
						||
  add_field(_realfld, 108, 13); // Saldo
 | 
						||
  add_field(_alfafld,-108,  1, "Sezione");  // Sezione
 | 
						||
  add_field(_realfld, 109, 13); // Saldo giornaliero
 | 
						||
  add_field(_alfafld,-109,  1, "Sezione");  // Sezione giornaliera
 | 
						||
 | 
						||
  const bool show_cms = main_app().has_module(CMAUT) || main_app().has_module(CAAUT);
 | 
						||
  if (show_cms)
 | 
						||
    add_field(_alfafld, 110, 40); // Commessa
 | 
						||
}
 | 
						||
  
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TGrid_mask
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
class TGrid_mask : public TMask
 | 
						||
{
 | 
						||
  TMastrini_grid* _grid;
 | 
						||
  
 | 
						||
protected:  // TMask
 | 
						||
  virtual TMask_field* parse_field(TScanner& sc);
 | 
						||
  virtual bool on_key(KEY k);
 | 
						||
  virtual long handler(WINDOW win, EVENT* ep);
 | 
						||
 | 
						||
  static bool link_handler(TMask_field& f, KEY k);
 | 
						||
  static bool new_handler(TMask_field& f, KEY k);
 | 
						||
  static bool edit_handler(TMask_field& f, KEY k);
 | 
						||
  static bool export_handler(TMask_field& f, KEY k);
 | 
						||
  
 | 
						||
public:
 | 
						||
  TMastrini_grid& grid() { CHECK(_grid, "What's grid?"); return *_grid; }
 | 
						||
 | 
						||
  TGrid_mask();
 | 
						||
  virtual ~TGrid_mask() { }
 | 
						||
}; 
 | 
						||
 | 
						||
TGrid_mask::TGrid_mask() 
 | 
						||
          : _grid(NULL)
 | 
						||
{
 | 
						||
  read_mask("cg3600b", 0, 0);
 | 
						||
  set_handler(DLG_LINK,   link_handler);
 | 
						||
  set_handler(DLG_NEWREC, new_handler);
 | 
						||
  set_handler(DLG_EDIT,   edit_handler);
 | 
						||
  set_handler(DLG_EXPORT, export_handler);
 | 
						||
 | 
						||
  const bool show_cms = main_app().has_module(CMAUT) || main_app().has_module(CAAUT);
 | 
						||
  if (!show_cms)
 | 
						||
    _grid->grid().show_column(1110, false); // Nasconde la commessa
 | 
						||
}
 | 
						||
 | 
						||
TMask_field* TGrid_mask::parse_field(TScanner& sc)
 | 
						||
{         
 | 
						||
  TMask_field* f;
 | 
						||
  if (sc.key() == "SP")
 | 
						||
    f = _grid = new TMastrini_grid(this);
 | 
						||
  else
 | 
						||
    f = TMask::parse_field(sc);
 | 
						||
  return f;  
 | 
						||
} 
 | 
						||
 | 
						||
bool TGrid_mask::link_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TGrid_mask& gm = (TGrid_mask&)f.mask();
 | 
						||
    TMastrini_grid& grid = gm.grid();
 | 
						||
    const long rec = grid.selected();
 | 
						||
    if (rec >= 0 && rec < grid.items())
 | 
						||
      grid.on_record_button(rec);
 | 
						||
  }  
 | 
						||
  return true;
 | 
						||
} 
 | 
						||
 | 
						||
bool TGrid_mask::new_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TExternal_app app("cg2 -0");
 | 
						||
    const bool refresh = app.run() == 0;
 | 
						||
    if (refresh && yesno_box(TR("Si desidera aggiornare il mastrino?")))
 | 
						||
    {
 | 
						||
      TGrid_mask& gm = (TGrid_mask&)f.mask();
 | 
						||
      TMastrini_grid& grid = gm.grid();
 | 
						||
      grid.reread();
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_mask::edit_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TGrid_mask& gm = (TGrid_mask&)f.mask();
 | 
						||
    TMastrini_grid& grid = gm.grid();
 | 
						||
    TMastrino_set ms(grid);
 | 
						||
 | 
						||
    TFilename n; n.tempdir(); n.add("mastrino.xls");
 | 
						||
    ms.save_as(n);
 | 
						||
    ok = xvt_sys_goto_url(n, "open") != FALSE;
 | 
						||
    if (!ok) 
 | 
						||
      ok = export_handler(f, k); // Se non parte Excel salvo altrove
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_mask::export_handler(TMask_field& f, KEY k)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  if (k == K_SPACE)
 | 
						||
  {
 | 
						||
    TFilename n; n.tempdir(); n.add("mastrino.xls");
 | 
						||
    FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(n, &fs);
 | 
						||
    if (xvt_dm_post_file_save(&fs, f.prompt()) == FL_OK)
 | 
						||
    {
 | 
						||
      xvt_fsys_convert_fspec_to_str(&fs, n.get_buffer(), n.size());
 | 
						||
      TGrid_mask& gm = (TGrid_mask&)f.mask();
 | 
						||
      TMastrini_grid& grid = gm.grid();
 | 
						||
      TMastrino_set ms(grid);
 | 
						||
      ms.save_as(n);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TGrid_mask::on_key(KEY k)
 | 
						||
{
 | 
						||
  switch (k)
 | 
						||
  {                         
 | 
						||
  case K_ENTER:  
 | 
						||
  case K_CTRL+'+':  
 | 
						||
  case K_CTRL+'-':
 | 
						||
    if (focus_field().dlg() == _grid->dlg())
 | 
						||
    {
 | 
						||
      const long rec = grid().selected();
 | 
						||
      _grid->on_dbl_cell(rec, DLG_USER);
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  default:     
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  
 | 
						||
  return TMask::on_key(k);
 | 
						||
}  
 | 
						||
 | 
						||
long TGrid_mask::handler(WINDOW win, EVENT* ep)
 | 
						||
{   
 | 
						||
  static TGrid_field* _last_grid = NULL;
 | 
						||
                      
 | 
						||
  if (ep->type == E_MOUSE_DOWN && ep->v.mouse.button == 1)
 | 
						||
  {   
 | 
						||
    _last_grid = NULL;
 | 
						||
 | 
						||
    RCT rct; _grid->get_rect(rct);
 | 
						||
    if (xvt_rect_has_point(&rct, ep->v.mouse.where))
 | 
						||
      _last_grid = _grid;
 | 
						||
  
 | 
						||
    if (_last_grid)
 | 
						||
    {
 | 
						||
      //TGrid_field& sht = (TGrid_field&)*_last_grid;
 | 
						||
      MENU_ITEM* menu = xvt_res_get_menu(BROWSE_BAR);
 | 
						||
 | 
						||
      if (menu != NULL)
 | 
						||
      {         
 | 
						||
        const PNT& p = ep->v.mouse.where;
 | 
						||
        xvt_menu_popup(menu->child, win, p, XVT_POPUP_CENTER, 0);
 | 
						||
        xvt_res_free_menu_tree(menu);       
 | 
						||
      }  
 | 
						||
      return 0L;
 | 
						||
    }
 | 
						||
  }      
 | 
						||
  if (ep->type == E_COMMAND)
 | 
						||
  {
 | 
						||
    if (_last_grid)
 | 
						||
    {
 | 
						||
      switch (ep->v.cmd.tag)
 | 
						||
      {     
 | 
						||
				case BROWSE_BAR+1: _last_grid->save_columns_order(); break;            
 | 
						||
				case BROWSE_BAR+2: _last_grid->reset_columns_order(); break;
 | 
						||
				case BROWSE_BAR+3: _last_grid->on_key(K_F11); break;
 | 
						||
				default: break;  
 | 
						||
      }
 | 
						||
      return 0L;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return TMask::handler(win, ep);
 | 
						||
}  
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TQuery_mask
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
         
 | 
						||
bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | 
						||
{
 | 
						||
  switch (o.dlg())
 | 
						||
  {
 | 
						||
  case F_TIPO:
 | 
						||
    if (e == fe_modify)
 | 
						||
    {
 | 
						||
      const TString& tipo = o.get();
 | 
						||
 | 
						||
			if (tipo != _last_tipo)
 | 
						||
			{
 | 
						||
	 			_last_tipo = tipo;
 | 
						||
				if (tipo.full())
 | 
						||
				{
 | 
						||
          // Controllo se il mastro corrente <20> gi<67> compatibile col tipo C/F
 | 
						||
          if (!field(F_CONTO).empty())
 | 
						||
          {
 | 
						||
            TString8 key; key.format("%d|%d", get_int(F_GRUPPO), get_int(F_CONTO));
 | 
						||
            const TString& tmcf = cache().get(LF_PCON, key, PCN_TMCF);
 | 
						||
            if (tmcf == tipo)
 | 
						||
              return true; 
 | 
						||
          }
 | 
						||
          // Cerco il primo mastro conforme al tipo C/F selezionato
 | 
						||
					TWait_cursor hourglass;
 | 
						||
					TString80 query;
 | 
						||
					query  << "USE " << LF_PCON << " SELECT " << PCN_TMCF << "=\"" << tipo << "\"";
 | 
						||
					TISAM_recordset conti(query);
 | 
						||
					if (conti.move_first())
 | 
						||
					{
 | 
						||
						set(F_GRUPPO, conti.get(PCN_GRUPPO).as_int(), 0x2);
 | 
						||
						set(F_CONTO, conti.get(PCN_CONTO).as_int(), 0x2);
 | 
						||
					}
 | 
						||
				}
 | 
						||
			}
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case F_CLIENTE:
 | 
						||
  case F_FORNITORE:
 | 
						||
    if (e == fe_modify && !o.empty())
 | 
						||
    {
 | 
						||
      const TRectype& rec = ((TEdit_field&)o).browse()->cursor()->curr();
 | 
						||
      const int g = rec.get_int(CLI_GRUPPO);
 | 
						||
      const int c = rec.get_int(CLI_CONTO);
 | 
						||
      if (g > 0 && c > 0)
 | 
						||
      {
 | 
						||
        set(F_GRUPPO, g, 0x2);
 | 
						||
        set(F_CONTO, c, 0x2);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case F_ESERCIZIO:
 | 
						||
    if (e == fe_modify || e == fe_close)
 | 
						||
    {
 | 
						||
      TEsercizi_contabili esc;                 
 | 
						||
      const int anno = atoi(o.get());
 | 
						||
      if (esc.exist(anno))
 | 
						||
      {
 | 
						||
        TDate dd = get(F_DADATA);
 | 
						||
        if (esc.date2esc(dd) != anno)
 | 
						||
          set(F_DADATA, esc[anno].inizio());
 | 
						||
        dd = get(F_ADATA);
 | 
						||
        if (esc.date2esc(dd) != anno)
 | 
						||
          set(F_ADATA, esc[anno].fine());
 | 
						||
      }
 | 
						||
      else                                     
 | 
						||
      {
 | 
						||
        if (anno > 0)
 | 
						||
          return error_box(FR("Esercizio inesistente: %d"), anno);
 | 
						||
      }  
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case F_DADATA:
 | 
						||
  case F_ADATA:
 | 
						||
    if (e == fe_close)
 | 
						||
    {                        
 | 
						||
      const TEsercizi_contabili esercizi;
 | 
						||
      int codice_esercizio = get_int(F_ESERCIZIO);
 | 
						||
      if (codice_esercizio <= 0)
 | 
						||
      {
 | 
						||
        const short id_altra_data = o.dlg() == F_DADATA ? F_ADATA : F_DADATA;
 | 
						||
        const TDate d = get(id_altra_data);
 | 
						||
        if (d.ok())
 | 
						||
          codice_esercizio = esercizi.date2esc(d);
 | 
						||
      }              
 | 
						||
    
 | 
						||
      if (o.empty())
 | 
						||
      {
 | 
						||
        if (codice_esercizio == 0)
 | 
						||
          return error_box(TR("E' necessario specificare almeno una data."));
 | 
						||
        return true;  
 | 
						||
      }
 | 
						||
 | 
						||
      const TDate d = o.get();
 | 
						||
      const int esercizio = esercizi.date2esc(d);
 | 
						||
      if (get_int(F_ESERCIZIO) != 0)
 | 
						||
      {
 | 
						||
        if (esercizio != codice_esercizio)
 | 
						||
          return error_box(FR("La data deve appartenere all'esercizio %d"), codice_esercizio);
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        if (esercizio == 0)
 | 
						||
          return error_box(TR("La data deve appartenere ad un esercizio contabile"));
 | 
						||
      }    
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case DLG_FINDREC:
 | 
						||
    if (e == fe_button)
 | 
						||
    {
 | 
						||
      short id;
 | 
						||
      switch (get(F_TIPO)[0])
 | 
						||
      {
 | 
						||
      case 'C': id = F_CLIENTE;    break;
 | 
						||
      case 'F': id = F_FORNITORE;  break;
 | 
						||
      default : id = F_SOTTOCONTO; break;
 | 
						||
      }
 | 
						||
      field(id).on_key(K_F9);
 | 
						||
    }
 | 
						||
    break;
 | 
						||
  case DLG_CONFIG:
 | 
						||
    if (e == fe_button)
 | 
						||
      _gm->grid().set_colors();
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    break;
 | 
						||
  }
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
  
 | 
						||
TQuery_mask::TQuery_mask(TGrid_mask* gm) : TAutomask("cg3600a"), _gm(gm), _last_tipo("")
 | 
						||
{ }
 | 
						||
   
 | 
						||
void TQuery_mask::do_query()
 | 
						||
{ 
 | 
						||
  const char t = get(F_TIPO)[0];
 | 
						||
  const int  g = get_int(F_GRUPPO);
 | 
						||
  const int  c = get_int(F_CONTO);
 | 
						||
  const long s = get_long((t <= ' ') ? F_SOTTOCONTO : ((t == 'C') ? F_CLIENTE : F_FORNITORE));
 | 
						||
  const TBill conto(g, c, s, t);
 | 
						||
 | 
						||
  const int annoes = get_int(F_ESERCIZIO);
 | 
						||
  const TDate da_data(get(F_DADATA));
 | 
						||
  const TDate a_data(get(F_ADATA));
 | 
						||
 | 
						||
  const TString& da_caus = get(F_DACAUSALE);
 | 
						||
  const TString& a_caus = get(F_ACAUSALE);
 | 
						||
  const bool provv = get_bool(F_PROVVIS);
 | 
						||
 | 
						||
  conto.set(*_gm, F_GRUPPO, F_CONTO, F_SOTTOCONTO, 0, F_DESSOTTOC);
 | 
						||
	TMastrini_grid& gf = _gm->grid();
 | 
						||
  
 | 
						||
  gf.set_contsep(get_bool(F_ST_CONTSEP));
 | 
						||
  gf.read(conto, annoes, da_data, a_data, da_caus, a_caus, provv);
 | 
						||
	gf.select(get_bool(F_END) ? gf.items() -1 : 0);        
 | 
						||
 | 
						||
  _gm->run();
 | 
						||
} 
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TMastrini_video
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
bool TMastrini_video::create()
 | 
						||
{                          
 | 
						||
  xvtil_statbar_set("", TRUE);
 | 
						||
  open_files(LF_CAUSALI, LF_MOV, LF_PCON, LF_RMOV, LF_SALDI, 0);
 | 
						||
  if (has_module(CMAUT))
 | 
						||
    open_files(LF_MOVANA, LF_RMOVANA, 0);
 | 
						||
  
 | 
						||
  _gm = new TGrid_mask;
 | 
						||
  _qm = new TQuery_mask(_gm);
 | 
						||
 | 
						||
  return TSkeleton_application::create();
 | 
						||
} 
 | 
						||
 | 
						||
bool TMastrini_video::destroy()
 | 
						||
{
 | 
						||
  delete _qm;  
 | 
						||
  delete _gm;
 | 
						||
  return TSkeleton_application::destroy();
 | 
						||
}
 | 
						||
 | 
						||
void TMastrini_video::main_loop()
 | 
						||
{
 | 
						||
  TQuery_mask& qm = *_qm;
 | 
						||
 | 
						||
  if (argc() > 2)
 | 
						||
  {
 | 
						||
    TFilename ininame = argv(2)+2;
 | 
						||
    if (ininame.exist())
 | 
						||
    {
 | 
						||
      TConfig ini(ininame, "24");
 | 
						||
      qm.set(F_ESERCIZIO,  ini.get(RMV_ANNOES));
 | 
						||
      qm.set(F_TIPO,       ini.get(RMV_TIPOC));
 | 
						||
      qm.set(F_GRUPPO,     ini.get(RMV_GRUPPO));
 | 
						||
      qm.set(F_CONTO,      ini.get(RMV_CONTO));
 | 
						||
      qm.set(F_SOTTOCONTO, ini.get(RMV_SOTTOCONTO));
 | 
						||
      qm.set(F_CLIENTE,    ini.get(RMV_SOTTOCONTO));
 | 
						||
      qm.set(F_FORNITORE,  ini.get(RMV_SOTTOCONTO));
 | 
						||
      qm.send_key(K_SPACE, DLG_OK);
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  const TEsercizi_contabili esercizi;
 | 
						||
  TDate inies, fines; 
 | 
						||
  int codesc = qm.get_int(F_ESERCIZIO);
 | 
						||
  if (!esercizi.exist(codesc))
 | 
						||
    codesc = esercizi.last();    
 | 
						||
  esercizi.code2range(codesc, inies, fines);
 | 
						||
  qm.set(F_ESERCIZIO, codesc);
 | 
						||
  qm.set(F_DADATA, inies);
 | 
						||
  qm.set(F_ADATA, fines);
 | 
						||
    
 | 
						||
  while (qm.run() == K_ENTER)
 | 
						||
    qm.do_query();
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Main
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
int cg3600(int argc, char* argv[])
 | 
						||
{          
 | 
						||
  TMastrini_video mv;
 | 
						||
  mv.run(argc, argv, TR("Mastrini"));
 | 
						||
  return 0;
 | 
						||
}
 |