Files correlati : ba0.exe ba1.exe Ricompilazione Demo : [ ] Commento : ba0.exe Vietato aggiungere ai preveriti voci di primo livello del menu ba1.exe Consente anche di aggiornare e non solo inserire da file .txt git-svn-id: svn://10.65.10.50/branches/R_10_00@21513 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1207 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1207 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <extcdecl.h>
 | |
| 
 | |
| #include <applicat.h>
 | |
| #include <automask.h>
 | |
| #include <colors.h>
 | |
| #include <filetext.h>
 | |
| #include <prefix.h>
 | |
| #include <relation.h>
 | |
| #include <sheet.h>
 | |
| #include <utility.h>
 | |
| 
 | |
| #include "ba1800.h"
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Utilities
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| HIDDEN int get_isamfiles()
 | |
| {
 | |
|   FileDes dir;
 | |
|   CGetFile(LF_DIR, &dir, _nolock, NORDIR);
 | |
|   return (int)dir.EOD;
 | |
| }
 | |
| 
 | |
| HIDDEN int str2isamfile(const TString& str)
 | |
| {
 | |
|   int logic_num = 0;
 | |
|   if (!str.blank())
 | |
|   {                                          
 | |
|     const int logic = atoi(str);
 | |
|     if (logic > 0)
 | |
|     {              
 | |
|       if (logic > LF_DIR && logic < LF_EXTERNAL)
 | |
|       {
 | |
|         if (logic < get_isamfiles())
 | |
|         {
 | |
|           TBaseisamfile file(logic);
 | |
|           if (file.is_valid(FALSE) == NOERR)
 | |
|             logic_num = logic;
 | |
|         }  
 | |
|       }
 | |
|     }  
 | |
|     else
 | |
|     {
 | |
|       const int len = str.len();
 | |
|       if (len == 3 || (str[0] == '%' && len == 4))
 | |
|       {
 | |
|         const int first = len == 3 ? 0 : 1;
 | |
|         if (isalpha(str[first]) && isalnum(str[first+1]) && isalnum(str[first+2]))
 | |
|           logic_num = str[0] == '%' ? LF_TABCOM : LF_TAB;
 | |
|       }
 | |
|     }  
 | |
|   }
 | |
|   return logic_num;
 | |
| }
 | |
| 
 | |
| HIDDEN int choose_isamfile(int selected)
 | |
| {
 | |
|   TArray_sheet sht(-1,-1,-4,-4,TR("Selezione archivio"), HR("Codice|Descrizione archivio@70"));
 | |
|   TToken_string tt(80);
 | |
|   
 | |
|   long sel = 0;
 | |
|   
 | |
|   const int nfiles = get_isamfiles();
 | |
|   for (int logic = LF_TABCOM; logic < nfiles; logic++)
 | |
|   {     
 | |
|     if (logic == selected)
 | |
|       sel = sht.items();
 | |
|     const TFixed_string desc = prefix().description(logic);
 | |
|     if (desc.full() && desc.compare("File non presente", -1, true) != 0)
 | |
|     {
 | |
|       tt.format("%d", logic);
 | |
|       tt.add(desc);
 | |
|       sht.add(tt);
 | |
|     }  
 | |
|   }
 | |
|   
 | |
|   sht.select(sel);
 | |
|   if (sht.run() == K_ENTER)
 | |
|   {
 | |
|     sel = sht.selected();
 | |
|     selected = sht.row(sel).get_int(0);
 | |
|   }
 | |
|   else
 | |
|     selected = 0;  
 | |
|   return selected;
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TColumnizer_win & TColumnizer_field
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TColumnizer_field;
 | |
| 
 | |
| class TColumnizer_win : public TField_window
 | |
| { 
 | |
|   enum { RULER_HEIGHT = 2, NUM_WIDTH = 5 };
 | |
| 
 | |
|   TString_array _rows;        // Righe di testo da stampare
 | |
|   TPointer_array _column;     // Array delle posizioni di inizio campo
 | |
|   bool _clickable;            // E' possibile cliccare
 | |
| 
 | |
| protected: // TScroll_window
 | |
|   virtual long handler(WINDOW win, EVENT* ep);
 | |
|   virtual void update();
 | |
| 
 | |
| protected: // Internal use
 | |
|   int on_column(long col);                                            
 | |
| 
 | |
| public:
 | |
|   void recalc_layout(int dx, int dy);
 | |
| 
 | |
|   bool clickable() const { return _clickable; }
 | |
|   void set_clickable(bool on = TRUE) { _clickable = on; }
 | |
|   
 | |
|   void destroy_rows() { _rows.destroy(); }
 | |
|   void add_row(const char* row) { _rows.add(row); }
 | |
|   
 | |
|   void destroy_columns() { _column.destroy(); }
 | |
|   long add_column(long col) { return _column.add_long(col); }
 | |
|   long get_column(int index) const { return _column.get_long(index); }
 | |
| 
 | |
|   TColumnizer_win(int x, int y, int dx, int dy, WINDOW parent, TColumnizer_field* field);
 | |
|   virtual ~TColumnizer_win() { }
 | |
| };
 | |
| 
 | |
| class TColumnizer_field : public TWindowed_field
 | |
| {   
 | |
| protected: // TWindowed_field
 | |
|   virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent)
 | |
|   { return new TColumnizer_win(x, y, dx, dy, parent, this); }
 | |
| 
 | |
| protected: // Internal use
 | |
|   TColumnizer_win& col_win() const 
 | |
|   { return (TColumnizer_win&)win(); }
 | |
|   
 | |
| public:
 | |
|   void destroy_rows() { col_win().destroy_rows(); }
 | |
|   void add_row(const char* row) { col_win().add_row(row); }
 | |
|   void recalc_layout(int dx, int dy) const { col_win().recalc_layout(dx, dy); }
 | |
|   int visible_rows() const { return col_win().rows() - 1; }
 | |
|   
 | |
|   void destroy_columns() { col_win().destroy_columns(); }
 | |
|   void add_column(long col) { col_win().add_column(col); }
 | |
|   long get_column(int index) const { return col_win().get_column(index); }
 | |
| 
 | |
|   TColumnizer_field(TMask* m) : TWindowed_field(m) { }
 | |
|   virtual ~TColumnizer_field() { }
 | |
| };
 | |
| 
 | |
| int TColumnizer_win::on_column(long col)
 | |
| {  
 | |
|   int index = -1;            
 | |
|   if (col > 0)
 | |
|   {              
 | |
|     int action = 1;  // 1 = Add, 2 = Remove
 | |
|     int i;
 | |
|     for (i = _column.items()-1; i >= 0; i--)
 | |
|     {
 | |
|       const long cur_col = _column.get_long(i);
 | |
|       if (cur_col == col)
 | |
|       {
 | |
|         action = 2;
 | |
|         break;
 | |
|       }  
 | |
|       if (cur_col < col)
 | |
|       {
 | |
|         action = 1;
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     TSheet_field& sf = owner().mask().sfield(F_FIELDS);
 | |
|     switch(action)
 | |
|     {
 | |
|     case 1:
 | |
|       index = _column.insert_long(col, i+1);
 | |
|       break;
 | |
|     case 2:
 | |
|       _column.destroy(i, TRUE);
 | |
|       index = i;
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }  
 | |
|   }    
 | |
|   return index;
 | |
| }
 | |
| 
 | |
| void TColumnizer_win::update()
 | |
| {
 | |
|   const int x = int(origin().x);  
 | |
|   const int maxx = x + columns() + 1;
 | |
|   const int y = int(origin().y);  
 | |
|   const int maxy = y + rows() + 1;
 | |
|   int i;
 | |
|   TString80 str; 
 | |
| 
 | |
|   TField_window::update();
 | |
| 
 | |
|   set_color(NORMAL_COLOR, NORMAL_BACK_COLOR);
 | |
|   for (i = y; i < maxy-RULER_HEIGHT; i++)
 | |
|   {
 | |
|     TToken_string* row = (TToken_string*)_rows.objptr(i);
 | |
|     if (row)
 | |
|       stringat(NUM_WIDTH, i+RULER_HEIGHT, _rows.row(i));
 | |
|     else
 | |
|       break;  
 | |
|   }  
 | |
|   
 | |
|   set_brush(DISABLED_BACK_COLOR);
 | |
| 
 | |
|   bar(x, y, maxx, y+RULER_HEIGHT);
 | |
|   TString points(maxx); 
 | |
|   points.fill('.');
 | |
|   for (int n = x+1; n < maxx; n++) 
 | |
|   {
 | |
|     if ((n % 5) == 0)
 | |
|     {
 | |
|       if ((n & 0x1) == 0)
 | |
|       {
 | |
|         str.format("%d", n);
 | |
|         points.overwrite(str, n - str.len());
 | |
|       }
 | |
|       else
 | |
|         points.overwrite(":", n-1);
 | |
|     }
 | |
|   }  
 | |
|   stringat(NUM_WIDTH, y, points);
 | |
|   
 | |
|   bar(x, y, x+NUM_WIDTH, maxy);
 | |
|   for (i = y; i < maxy; i++)
 | |
|   {         
 | |
|     str.format("%*d", NUM_WIDTH, i+1);
 | |
|     stringat(x, i+RULER_HEIGHT, str);
 | |
|   }  
 | |
| 
 | |
|   set_pen(COLOR_BLACK);
 | |
|   
 | |
|   int last_column = 0;
 | |
|   for (i = 0; i < _column.items(); i++)
 | |
|   {
 | |
|     const int j = (int)_column.get_long(i);
 | |
|     if (j > x)  
 | |
|     {
 | |
|       _pixmap = TRUE;                
 | |
|       line((j+NUM_WIDTH)*CHARX, (y+1)*CHARY, (j+NUM_WIDTH)*CHARX, maxy*CHARY);
 | |
|       _pixmap = FALSE;
 | |
|     }               
 | |
|     
 | |
|     const int available = j-last_column;
 | |
|     str.format("%d(%d)", i+1, available);
 | |
|     int len = str.len();
 | |
|     if (len > available)
 | |
|     {
 | |
|       len = str.find('(');
 | |
|       str.cut(len);
 | |
|     }
 | |
|     if (len <= available)
 | |
|     {                   
 | |
|       int cx = (j+last_column-len) / 2;
 | |
|       if (cx >= x)
 | |
|         stringat(cx+NUM_WIDTH, y+1, str);
 | |
|     }      
 | |
| 
 | |
|     last_column = j;
 | |
|   }
 | |
|   
 | |
|   _pixmap = TRUE;                
 | |
|   line((x+NUM_WIDTH)*CHARX, (y+1)*CHARY, maxx*CHARX, (y+1)*CHARY);
 | |
|   line(x*CHARX, (y+RULER_HEIGHT)*CHARY, maxx*CHARX, (y+RULER_HEIGHT)*CHARY);
 | |
|   line((x+NUM_WIDTH)*CHARX, y*CHARY, (x+NUM_WIDTH)*CHARX, maxy*CHARY);
 | |
|   _pixmap = FALSE;
 | |
| }
 | |
| 
 | |
| long TColumnizer_win::handler(WINDOW win, EVENT* ep)
 | |
| {             
 | |
|   switch(ep->type)  
 | |
|   {
 | |
|   case E_MOUSE_DOWN:
 | |
|     if (_clickable)
 | |
|     {
 | |
|       long column = (ep->v.mouse.where.h + CHARX/2) / CHARX;
 | |
|       column += origin().x - NUM_WIDTH;
 | |
|       if (on_column(column) >= 0)
 | |
|         force_update();
 | |
|     }  
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return TField_window::handler(win, ep);
 | |
| }
 | |
| 
 | |
| void TColumnizer_win::recalc_layout(int dx, int dy)
 | |
| {            
 | |
|   long maxy = _rows.items() - rows()/2 + 1;
 | |
|   long maxx = dx;
 | |
|   if (maxx <= 0)
 | |
|     maxx = _column.get_long(_column.items()-1) + 384;
 | |
|   maxx -= columns()/2 + NUM_WIDTH;
 | |
|   if (maxx < 0) maxx = 0;
 | |
|   if (maxy < 0) maxy = 0;
 | |
|   set_scroll_max(maxx, maxy);
 | |
|   update_thumb(0, 0);
 | |
|   force_update();
 | |
| }
 | |
| 
 | |
| TColumnizer_win::TColumnizer_win(int x, int y, int dx, int dy, 
 | |
|                                  WINDOW parent, TColumnizer_field* field) 
 | |
|                : TField_window(x, y, dx, dy, parent, field), 
 | |
|                  _clickable(field->enabled())
 | |
| { 
 | |
|   set_scroll_max(columns(), rows());
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TWizard_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TWizard_mask : public TAutomask
 | |
| {        
 | |
|   TRelation* _rel;
 | |
|   TRelation_description* _reldesc;
 | |
| 
 | |
|   bool _frozen;
 | |
| 
 | |
| protected:  // TMask
 | |
|   virtual TMask_field* parse_field(TScanner& scanner);
 | |
| 
 | |
| protected: // TAutomask
 | |
|   virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly);
 | |
| 
 | |
| protected: // Internal use only
 | |
|   bool file_open(TFilename& name) const;
 | |
|   void load_ini(const TString& ininame);
 | |
|   void save_ini(const TFilename& ininame) const;
 | |
|   bool load_aga(const TFilename& name);
 | |
|   void file_preview() const;
 | |
|   bool is_aga_file(const TFilename& name) const;
 | |
|   bool import_file();
 | |
| 
 | |
|   TRelation_description* rel_desc(int logicnum);
 | |
|  
 | |
|   // First non-static handlers in history!
 | |
|   bool file_handler(TOperable_field& f, TField_event e);
 | |
|   bool ini_handler(TOperable_field& f, TField_event e);
 | |
|   bool isamfile_handler(TOperable_field& f, TField_event e);
 | |
| 
 | |
| public:  
 | |
|   TRelation_description* rel_desc();
 | |
| 
 | |
|   TWizard_mask();
 | |
|   virtual ~TWizard_mask();
 | |
| };
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TFields_mask
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TFields_mask : public TAutomask
 | |
| { 
 | |
|   
 | |
| protected: // Internal use 
 | |
|   bool field_handler(TOperable_field& of, TField_event fe);
 | |
|  
 | |
| public:
 | |
|   virtual bool on_field_event(TOperable_field& of, TField_event fe, long jolly);
 | |
|   TRelation_description* rel_desc() const;
 | |
|   
 | |
|   TFields_mask(const char* name, int number);
 | |
|   virtual ~TFields_mask();
 | |
| };
 | |
| 
 | |
| bool TFields_mask::on_field_event(TOperable_field& of, TField_event fe, long jolly)
 | |
| {  
 | |
|   bool ok = TRUE;
 | |
|   switch(of.dlg())
 | |
|   {       
 | |
|   case F_FIELD:
 | |
|     ok = field_handler(of, fe);
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TRelation_description* TFields_mask::rel_desc() const
 | |
| {
 | |
|   TSheet_field* sf = get_sheet();
 | |
|   TWizard_mask& wm = (TWizard_mask&)sf->mask();
 | |
|   TRelation_description* rd = wm.rel_desc();
 | |
|   return rd;
 | |
| }
 | |
| 
 | |
| bool TFields_mask::field_handler(TOperable_field& of, TField_event fe)
 | |
| {           
 | |
|   bool ok = TRUE;
 | |
| 
 | |
|   if (fe == fe_button)
 | |
|   {                             
 | |
|     TRelation_description* rd = rel_desc();
 | |
|     if (rd)
 | |
|     {
 | |
|       if (rd->choose_field(of.get()))
 | |
|       {
 | |
|         of.set(rd->field_name());
 | |
|         fe = fe_modify;
 | |
|       }  
 | |
|     }  
 | |
|     else
 | |
|       ok = error_box(TR("Selezionare un file valido"));
 | |
|   }
 | |
| 
 | |
|   if (fe == fe_modify || fe_close)
 | |
|   {                               
 | |
|     const TString& n = of.get();
 | |
|     if (n.not_empty())
 | |
|     {
 | |
|       TRelation_description* rd = rel_desc();
 | |
|       if (rd)
 | |
|       {
 | |
|         const char* d = rd->get_field_description(n);
 | |
|         if (d && *d)
 | |
|           set(F_DESCR, d);
 | |
|         else
 | |
|           ok = error_box(FR("Il campo %s non esiste"), 
 | |
|                          (const char*)n, rd->file_desc());
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| TFields_mask::TFields_mask(const char* name, int number)
 | |
|             : TAutomask(name, number)
 | |
| {
 | |
| }
 | |
| 
 | |
| TFields_mask::~TFields_mask()
 | |
| {
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TFields_sheet
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TFields_sheet : public TSheet_field
 | |
| {     
 | |
|   TFields_mask* _sheet_mask;
 | |
|  
 | |
| protected: // TSheet_field
 | |
|   virtual void create(WINDOW win);
 | |
| 
 | |
| public:
 | |
|   void describe_fields();
 | |
|   virtual TMask& sheet_mask() const;
 | |
| 
 | |
|   TFields_sheet(TAutomask* m);
 | |
|   virtual ~TFields_sheet();
 | |
| };
 | |
| 
 | |
| TMask& TFields_sheet::sheet_mask() const
 | |
| {                    
 | |
|   return _sheet_mask ? *(TMask*)_sheet_mask : TSheet_field::sheet_mask();
 | |
| }
 | |
| 
 | |
| void TFields_sheet::create(WINDOW win)
 | |
| {
 | |
|   TSheet_field::create(win);
 | |
|  
 | |
|   const TFilename& name = sheet_mask().source_file();
 | |
|   const int number = sheet_mask().number();
 | |
|   
 | |
|   _sheet_mask = new TFields_mask(name, number);
 | |
|   _sheet_mask->set_sheet(this);
 | |
| }
 | |
| 
 | |
| void TFields_sheet::describe_fields()
 | |
| {
 | |
|   TRelation_description* rd = _sheet_mask->rel_desc();
 | |
|   if (rd)
 | |
|   {
 | |
|     TString str;
 | |
|     for (int r = items()-1; r >= 0; r--)
 | |
|     {           
 | |
|       TToken_string& riga = row(r);
 | |
|       str = riga.get(0);
 | |
|       str = rd->get_field_description(str);
 | |
|       if (str.not_empty()) 
 | |
|         riga.add(str, F_DESCR-FIRST_FIELD);
 | |
|     }
 | |
|     force_update();
 | |
|   }  
 | |
| }
 | |
| 
 | |
| TFields_sheet::TFields_sheet(TAutomask* m)
 | |
|              : TSheet_field(m), _sheet_mask(NULL)
 | |
| {
 | |
| }
 | |
| 
 | |
| TFields_sheet::~TFields_sheet()
 | |
| {
 | |
|   if (_sheet_mask)
 | |
|     delete _sheet_mask;
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::file_open(TFilename& fname) const
 | |
| {
 | |
|   DIRECTORY dir; 
 | |
|   xvt_fsys_get_dir(&dir); // Save dir
 | |
| 
 | |
|   FILE_SPEC fs;
 | |
|   xvt_fsys_convert_str_to_fspec(fname, &fs);
 | |
|     
 | |
|   const bool good = xvt_dm_post_file_open(&fs, TR("Selezionare il file ...")) == FL_OK;
 | |
|   xvt_fsys_set_dir(&dir); // Restore dir
 | |
|                  
 | |
|   if (good)                 
 | |
|     fname = fs.name;
 | |
|   
 | |
|   return good;
 | |
| }
 | |
| 
 | |
| void TWizard_mask::load_ini(const TString& ininame)
 | |
| {                 
 | |
|   TWait_cursor hourglass;
 | |
|   if (!_frozen)
 | |
|   {
 | |
|     _frozen = TRUE;
 | |
|   
 | |
|     TConfig ini(ininame, "MAIN");
 | |
|     const int recsize = ini.get_int("RECORDSIZE");
 | |
|     if (recsize > 0)
 | |
|     {                    
 | |
|       set(F_FIXEDLEN, "X", TRUE);
 | |
|       set(F_RECLEN, recsize, TRUE);
 | |
|     }
 | |
|     else
 | |
|       set(F_RECSEP, ini.get("RECORDSEP").left(4), TRUE);
 | |
|     set(F_SKIPLINES, ini.get_int("SKIPLINES"));
 | |
|     
 | |
|     const TString16 fldsep = ini.get("FIELDSEP").left(1);
 | |
|     set(F_FIELDSEP, fldsep, TRUE);
 | |
|     
 | |
|     ini.set_paragraph("RECORD");
 | |
|   
 | |
|     if (fldsep.empty())
 | |
|     {                                                                             
 | |
|       TColumnizer_field& cf = (TColumnizer_field&)field(F_COLUMNIZER);
 | |
|       for (int i = 0; ; i++)
 | |
|       {                        
 | |
|         if (i > 0) 
 | |
|         {
 | |
|           const long position = ini.get_long("POSITION", NULL, i);
 | |
|           if (position > 0)
 | |
|             cf.add_column(position);
 | |
|           else
 | |
|             break;  
 | |
|         }    
 | |
|         else  
 | |
|           cf.destroy_columns();
 | |
|       }
 | |
|     }
 | |
|     
 | |
|     TString use = ini.get("USE");
 | |
|     if (use.not_empty())
 | |
|       set(F_ISAM, use);
 | |
|     
 | |
|     TRelation_description* rd = rel_desc();
 | |
|     
 | |
|     TFields_sheet& fs = (TFields_sheet&)sfield(F_FIELDS);
 | |
|     TFieldref fr;
 | |
|     for (int i = 0; ini.exist("NAME", i) || ini.exist("POSITION", i); i++)
 | |
|     {                  
 | |
|       const TString& campo = ini.get("FIELD", NULL, i);
 | |
|       TToken_string& row = fs.row(i);
 | |
|       if (campo.not_empty())
 | |
|       {
 | |
|         fr = campo;
 | |
|         row = fr.name();
 | |
|         
 | |
|         if (rd == NULL)
 | |
|         {
 | |
|           int isam = fr.file();
 | |
|           if (isam)
 | |
|           {
 | |
|             set(F_ISAM, isam);
 | |
|             rd = rel_desc();
 | |
|           }  
 | |
|         }
 | |
|         
 | |
|         if (rd)
 | |
|           row.add(rd->get_field_description(fr.name()));
 | |
|       }  
 | |
|     }
 | |
|     fs.force_update();
 | |
|     _frozen = FALSE;  
 | |
|   }
 | |
| }
 | |
| 
 | |
| void TWizard_mask::save_ini(const TFilename& ininame) const
 | |
| {                 
 | |
|   if (!ininame.blank())
 | |
|   {
 | |
|     if (!ininame.exist() || 
 | |
|         yesno_box(FR("Si desidera sovrascrivere il file %s"), (const char*)ininame))
 | |
|     {    
 | |
|       TConfig ini(ininame, "MAIN");
 | |
|       ini.remove_all();
 | |
|       ini.set("RECORDSEP", get(F_RECSEP));
 | |
|       ini.set("RECORDSIZE", get(F_RECLEN));
 | |
|       ini.set("SKIPLINES", get(F_SKIPLINES));
 | |
|       const TString& fieldsep = get(F_FIELDSEP);
 | |
|       ini.set("FIELDSEP", fieldsep);
 | |
|       ini.set("TYPEFIELD", -1);
 | |
|  
 | |
|       ini.set_paragraph("RECORD");
 | |
|       ini.remove_all();
 | |
|       ini.set("USE", get(F_ISAM));
 | |
| 
 | |
|       if (fieldsep.empty())
 | |
|       {        
 | |
|         const TColumnizer_field& cf = (const TColumnizer_field&)field(F_COLUMNIZER);
 | |
|         long last_column = 0;
 | |
|         for (int i = 0; ; i++)
 | |
|         {
 | |
|           const long column = cf.get_column(i);
 | |
|           if (column <= 0)
 | |
|             break; 
 | |
|           const long len = column - last_column;
 | |
|           ini.set("POSITION", last_column, NULL, TRUE, i);  
 | |
|           ini.set("LENGTH", len, NULL, TRUE, i);
 | |
|           last_column = column;
 | |
|         }
 | |
|       }
 | |
|       
 | |
|       TSheet_field& sf = sfield(F_FIELDS);
 | |
|       FOR_EACH_SHEET_ROW(sf, r, row)
 | |
|       {                             
 | |
|         ini.set("FIELD", row->get(0), NULL, TRUE, r);
 | |
|         
 | |
|         const char* name = row->get(1);
 | |
|         if (name == NULL || *name <= ' ')
 | |
|           name = row->get(0);
 | |
|         ini.set("NAME", name, NULL, TRUE, r);
 | |
|       }
 | |
|     }  
 | |
|   }  
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::is_aga_file(const TFilename& name) const
 | |
| {
 | |
|   bool yes = xvt_str_compare_ignoring_case(name.ext(), "txt") == 0;
 | |
|   if (yes)
 | |
|   {
 | |
|     TScanner aga(name);
 | |
|     yes = aga.paragraph("Data"); // Esiste il paragrafo dati?
 | |
|   }
 | |
|   return yes;
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::load_aga(const TFilename& name)
 | |
| {   
 | |
|   TWait_cursor hourglass;
 | |
|   if (!_frozen)
 | |
|   {
 | |
|     _frozen = TRUE;
 | |
|     TSheet_field& sf = sfield(F_FIELDS);
 | |
|     TScanner aga(name);
 | |
|     TToken_string riga(1024);
 | |
|     TToken_string campo(15, ',');
 | |
|     TString isam;
 | |
|     bool inside_header = FALSE;
 | |
|     
 | |
|     while (aga.line().not_empty())
 | |
|     {     
 | |
|       riga = aga.token(); 
 | |
|   
 | |
|       if (riga.compare("[Data]", -1, TRUE) == 0)  
 | |
|       {
 | |
|         set(F_FIXEDLEN, "", TRUE);
 | |
|         set(F_RECLEN, "", TRUE);
 | |
|         set(F_RECSEP, "", TRUE);
 | |
|         set(F_FIELDSEP, "|", TRUE);
 | |
|         set(F_SKIPLINES, aga.linenum(), TRUE);
 | |
|         if (isam.not_empty())
 | |
|           set(F_ISAM, isam, TRUE);
 | |
|         break;
 | |
|       }
 | |
|   
 | |
|       if (inside_header)
 | |
|       {
 | |
|         if (riga.compare("Fields", 6, TRUE) == 0)  
 | |
|         {
 | |
|           const int uguale = riga.find('=');
 | |
|           if (uguale >= 0)
 | |
|           {
 | |
|             riga.ltrim(uguale+1);
 | |
|             for(campo = riga.get(0); campo.not_empty(); campo = riga.get())
 | |
|             {
 | |
|               sf.row(-1) = campo.get(0);
 | |
|               sf.check_row(sf.items()-1);
 | |
|             }
 | |
|           }
 | |
|         } else
 | |
|         if (riga.compare("File", 4, TRUE) == 0)  
 | |
|         {
 | |
|           const int uguale = riga.find('=');
 | |
|           if (uguale >= 0)
 | |
|           {
 | |
|             isam = riga.mid(uguale+1);
 | |
|             isam.trim();
 | |
|           }
 | |
|         }
 | |
|         else
 | |
|           inside_header = riga[0] != '[';
 | |
|       } 
 | |
|       else
 | |
|       {
 | |
|         if (riga.compare("[Header]", -1, TRUE) == 0)
 | |
|         {
 | |
|           sf.destroy();
 | |
|           inside_header = TRUE;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     _frozen = FALSE;
 | |
|   }
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| void TWizard_mask::file_preview() const
 | |
| {                 
 | |
|   TWait_cursor hourglass;
 | |
|   if (_frozen)
 | |
|     return;
 | |
|   
 | |
|   const int MAXLINE = 8192;
 | |
|   const bool fixedlen = get_bool(F_FIXEDLEN);
 | |
|   const int reclen = fixedlen ? get_int(F_RECLEN) : 0;
 | |
|   const long skiplines = get_long(F_SKIPLINES);
 | |
|   const TString& recsep = get(F_RECSEP);
 | |
|   const TString& fieldsep = get(F_FIELDSEP);
 | |
| 
 | |
|   const TString& fname = get(F_FILE);
 | |
|   int flags = ios::in;
 | |
|   if (fixedlen)
 | |
|     flags |= ios::binary;
 | |
|   ifstream f(fname, flags);
 | |
| 
 | |
|   if (fixedlen)
 | |
|   {
 | |
|     streamoff offset = reclen * skiplines;
 | |
|     f.seekg(offset, ios::beg);
 | |
|   }  
 | |
|   else
 | |
|   {
 | |
|     for (long s = skiplines; s > 0; s--)
 | |
|     {
 | |
|       if (*recsep)
 | |
|         f.ignore(MAXLINE, *recsep);
 | |
|       else  
 | |
|         f.ignore(MAXLINE, '\n');
 | |
|     }  
 | |
|   }
 | |
|   
 | |
|   TColumnizer_field& cf = (TColumnizer_field&)field(F_COLUMNIZER);
 | |
|   
 | |
|   int displines = get_int(F_DISPLINES);
 | |
|   if (displines <= 0) 
 | |
|     displines = cf.visible_rows();
 | |
|   
 | |
|   TString_array righe;
 | |
| 	int l;
 | |
|   for (l = 0; l < displines; l++)
 | |
|   {
 | |
|     righe.add(new TToken_string(MAXLINE), l);
 | |
|     TToken_string& riga = righe.row(l);
 | |
|     char* buff = riga.get_buffer();
 | |
|     
 | |
|     if (fixedlen)
 | |
|     {   
 | |
|       f.read(buff, reclen);
 | |
|       riga.cut(reclen);
 | |
|     }
 | |
|     else
 | |
|     {   
 | |
|       if (*recsep)
 | |
|       {
 | |
|         f.getline(buff, riga.size(), *recsep);
 | |
|         f.ignore(strlen(recsep)-1);
 | |
|       }  
 | |
|       else
 | |
|         f.getline(buff, riga.size());
 | |
|     }
 | |
|     if (f.eof()) 
 | |
|       break;
 | |
|   }
 | |
|   
 | |
|   if (fieldsep.blank())
 | |
|   {   
 | |
|     cf.enable();
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     TPointer_array maxlen;
 | |
|     int maxcol = 0;
 | |
|     int l;
 | |
|     for (l = righe.items()-1; l >= 0; l--)
 | |
|     {
 | |
|       TToken_string& riga = righe.row(l);
 | |
|       riga.separator(fieldsep[0]);
 | |
|       int col = 0;
 | |
|       FOR_EACH_TOKEN(riga, tok)
 | |
|       {
 | |
|         const long len = *tok ? strlen(tok) : 1;
 | |
|         if (len > maxlen.get_long(col))
 | |
|           maxlen.add_long(len, col);
 | |
|         col++;
 | |
|       }
 | |
|       if (col > maxcol)
 | |
|         maxcol = col;
 | |
|     }
 | |
|     cf.disable();
 | |
|     cf.destroy_columns();
 | |
|     long last_column = 0;
 | |
|     for (l = 0; l < maxcol; l++)
 | |
|     {
 | |
|       const long len = maxlen.get_long(l);
 | |
|       last_column += len;
 | |
|       cf.add_column(last_column);
 | |
|     }  
 | |
|     
 | |
|     TToken_string oldrow;
 | |
|     TString str;
 | |
|     for (l = righe.items()-1; l >= 0; l--)
 | |
|     {
 | |
|       TToken_string& riga = righe.row(l);
 | |
|       oldrow = riga;
 | |
|       riga.cut(0);
 | |
|       int col = 0;
 | |
|       FOR_EACH_TOKEN(oldrow, tok)
 | |
|       {
 | |
|         const int len = (int)maxlen.get_long(col);
 | |
|         str = tok;        
 | |
|         if (str[0] =='#' || real::is_real(str))
 | |
|           str.right_just(len);
 | |
|         else
 | |
|           str.left_just(len);
 | |
|         riga << str;
 | |
|         col++;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   cf.destroy_rows();
 | |
|   for (int m = 0; m < righe.items(); m++)
 | |
|   {
 | |
|     TToken_string& riga = righe.row(m);
 | |
|     cf.add_row(riga);
 | |
|   }  
 | |
|   cf.recalc_layout(reclen, righe.items());
 | |
| }   
 | |
| 
 | |
| TRelation_description* TWizard_mask::rel_desc(int logicnum)
 | |
| {             
 | |
|   if (_rel && _rel->lfile().num() != logicnum)
 | |
|   {
 | |
|     delete _rel;
 | |
|     _rel = NULL;
 | |
|     delete _reldesc;
 | |
|     _reldesc = NULL;
 | |
|   }
 | |
|   if (_rel == NULL && logicnum > 0)
 | |
|   {
 | |
|     _rel = new TRelation(logicnum);
 | |
|     _reldesc = new TRelation_description(*_rel);
 | |
|   }  
 | |
|     
 | |
|   return _reldesc;
 | |
| }
 | |
| 
 | |
| TRelation_description* TWizard_mask::rel_desc()
 | |
| {           
 | |
|   TRelation_description* rd = NULL;
 | |
|   const TString& isam = get(F_ISAM);
 | |
|   const int logicnum = str2isamfile(isam);
 | |
|   if (logicnum > 0)
 | |
|     rd = rel_desc(logicnum);
 | |
|   return rd;  
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::file_handler(TOperable_field& f, TField_event e)
 | |
| { 
 | |
|   bool ok = TRUE;
 | |
|   
 | |
|   if (e == fe_button)
 | |
|   {
 | |
|     TFilename n("*.txt");
 | |
|     if (file_open(n))
 | |
|     {
 | |
|       f.set(n);
 | |
|       e = fe_modify;
 | |
|     }  
 | |
|   }     
 | |
|   
 | |
|   if (e == fe_modify)
 | |
|   {            
 | |
|     TFilename n = f.get();
 | |
|     if (n.exist())
 | |
|     {    
 | |
|       if (is_aga_file(n))
 | |
|       {
 | |
|         load_aga(n);
 | |
|       }  
 | |
|       else
 | |
|       {
 | |
|         const char* ext[] = { "imp", "ini", NULL };
 | |
|         for (int e = 0; ext[e]; e++)
 | |
|         {
 | |
|           n.ext(ext[e]);
 | |
|           if (n.exist())
 | |
|           {
 | |
|             set(F_INI, n, TRUE);
 | |
|             return TRUE;
 | |
|           }  
 | |
|         }
 | |
|       }  
 | |
|       
 | |
|       n = n.name();
 | |
|       n.ext("");   
 | |
|       if ((n[0] == 'f' || n[0] == 'F') && atoi(n.mid(1,-1)))
 | |
|         n.ltrim(1);
 | |
|       if (str2isamfile(n))
 | |
|         set(F_ISAM, n, TRUE);
 | |
|       
 | |
|       file_preview();
 | |
|     }  
 | |
|     else
 | |
|       ok = error_box(TR("Il file non esiste"));
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::ini_handler(TOperable_field& f, TField_event e)
 | |
| {           
 | |
|   bool ok = TRUE;
 | |
|   switch (e)
 | |
|   {        
 | |
|   case fe_button:
 | |
|     {
 | |
|       TFilename n("*.imp");
 | |
|       if (file_open(n))
 | |
|         f.set(n);
 | |
|       else
 | |
|         break;  
 | |
|     }  
 | |
|   case fe_init:
 | |
|   case fe_modify:
 | |
|     {                       
 | |
|       const TFilename n = f.get();
 | |
|       const bool pieno = !n.blank();
 | |
|       enable(F_SAVE, pieno);
 | |
|       if (pieno)
 | |
|       {   
 | |
|         if (n.exist())
 | |
|         {
 | |
|           load_ini(n);
 | |
|           file_preview();
 | |
|         }  
 | |
|       }  
 | |
|     }
 | |
|     break;
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::isamfile_handler(TOperable_field& f, TField_event e)
 | |
| {          
 | |
|   bool ok = TRUE;
 | |
|   switch (e)
 | |
|   {
 | |
|   case fe_init:
 | |
|     disable(F_IMPORT);
 | |
|     break;
 | |
|   case fe_button:
 | |
|     {
 | |
|       int logicnum = str2isamfile(f.get());
 | |
|       logicnum = choose_isamfile(logicnum);
 | |
|       if (logicnum > 0)
 | |
|         f.set(logicnum);
 | |
|       else
 | |
|         break;
 | |
|     }
 | |
|   case fe_modify:
 | |
|     {              
 | |
|       bool can_import = str2isamfile(f.get()) > 0;
 | |
|       if (can_import)
 | |
|       {   
 | |
|         TFields_sheet& fs = (TFields_sheet&)sfield(F_FIELDS); 
 | |
|         fs.describe_fields();
 | |
|       }
 | |
|       else
 | |
|         ok = error_box(TR("File dati non valido"));
 | |
|       can_import &= fexist(get(F_FILE));
 | |
|       enable(F_IMPORT, can_import);
 | |
|       reset(F_ZAP);
 | |
|     }
 | |
|     break;
 | |
|   }  
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::import_file()
 | |
| {
 | |
|   bool ok = FALSE;
 | |
| 
 | |
|   const TFilename filename = get(F_FILE);
 | |
|   if (!filename.exist())
 | |
|     return error_box(FR("Il file %s non esiste"), (const char*)filename);
 | |
| 
 | |
|   const int logicnum = str2isamfile(get(F_ISAM));
 | |
|   if (logicnum <= 0)
 | |
|     return error_box(TR("E' necessario specificare un file di destinazione valido"));
 | |
| 
 | |
|   rel_desc(0);  // Chiude il file isam correntemente in uso, altrimenti niente _excllock
 | |
|   TSystemisamfile sif(logicnum);
 | |
|   int err = sif.open_ex(_excllock);
 | |
|   if (err != NOERR)
 | |
|     return error_box(FR("Impossibile aprire il file %d: errore %d"), logicnum, err);
 | |
|   const bool empty = sif.items() == 0L;
 | |
|   sif.close();
 | |
|     
 | |
|   if (get_bool(F_ZAP))  
 | |
|   {
 | |
|     if (!empty && yesno_box(FR("Procedere con l'azzeramento del file %d?"), logicnum))
 | |
|       sif.packfile(FALSE, TRUE);
 | |
|   }
 | |
|   
 | |
|   const TFilename ininame = get(F_INI);
 | |
|   if (ininame.exist())
 | |
|   { 
 | |
|     TFile_text txt(filename, ininame);
 | |
|     err = txt.open('r');
 | |
|     if (err == NOERR)
 | |
|     {
 | |
|       TRecord_text rec;
 | |
|       for (long numrec = 1; txt.read(rec) == NOERR; numrec++)
 | |
|       {
 | |
|         err = txt.autosave(rec);
 | |
|         if (err != NOERR)
 | |
|         {
 | |
|           ok = error_box(FR("Errore %d durante la scrittura del record %ld:"),
 | |
|                          err, numrec);
 | |
|           break;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     else  
 | |
|       ok = error_box(FR("Impossibile leggere il file %s"), (const char*)filename);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if (is_aga_file(filename))
 | |
|     {
 | |
|       err = sif.open_ex(_excllock);
 | |
|       if (err == NOERR)
 | |
|         ok = sif.load(filename) == NOERR;
 | |
|       else
 | |
|         ok = error_box(FR("Impossibile aprire il file %d: errore %d"), logicnum, err);
 | |
|       sif.close();
 | |
|     }
 | |
|     else
 | |
|       ok = error_box(FR("Il file %s non esiste"), (const char*)ininame);
 | |
|   }
 | |
|   return ok;
 | |
| }
 | |
| 
 | |
| bool TWizard_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
 | |
| {
 | |
|   bool ok = TRUE;
 | |
| 	
 | |
| 	if (jolly == 0)
 | |
| 	{
 | |
| 		switch(f.dlg())
 | |
| 		{
 | |
| 			case F_FILE:
 | |
| 				ok = file_handler(f, e);
 | |
| 				break;
 | |
| 			case F_INI:
 | |
| 				ok = ini_handler(f, e);
 | |
| 				break;
 | |
| 			case F_RECLEN:
 | |
| 			case F_RECSEP:  
 | |
| 			case F_FIELDSEP:
 | |
| 			case F_SKIPLINES:
 | |
| 			case F_DISPLINES:
 | |
| 			case F_FIXEDLEN:
 | |
| 				if (e == fe_modify)
 | |
| 					file_preview();
 | |
| 				break;  
 | |
| 			case F_ISAM:  
 | |
| 				ok = isamfile_handler(f, e);
 | |
| 				break;
 | |
| 			case F_SAVE:
 | |
| 				if (e == fe_button)
 | |
| 					save_ini(get(F_INI));
 | |
| 				break;  
 | |
| 			case F_IMPORT:  
 | |
| 				if (e == fe_button)
 | |
| 					import_file();
 | |
| 				break;  
 | |
| 			case F_COLUMNIZER:
 | |
| 				if (e == fe_init)
 | |
| 					file_preview();   // Indispensabile!
 | |
| 				break;
 | |
| 			default:
 | |
| 				break;  
 | |
| 		}         
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		TFields_sheet& fs = (TFields_sheet&)sfield(F_FIELDS); 
 | |
| 
 | |
| 		ok = ((TFields_mask&)fs.sheet_mask()).on_field_event(f, e, 0);
 | |
| 	}
 | |
|   return ok;
 | |
| }
 | |
|                                                  
 | |
| TMask_field* TWizard_mask::parse_field(TScanner& scanner)
 | |
| {
 | |
|   const TString& key = scanner.key();
 | |
|   if (key == "BR") 
 | |
|     return new TColumnizer_field(this);
 | |
|   if (key == "SP") 
 | |
|     return new TFields_sheet(this);
 | |
|   return TAutomask::parse_field(scanner);
 | |
| }
 | |
| 
 | |
| TWizard_mask::TWizard_mask()
 | |
|             : _frozen(FALSE), _reldesc(NULL), _rel(NULL)
 | |
| {                           
 | |
|   read_mask("ba1800a", 0, 1);
 | |
|   set_handlers();
 | |
| }
 | |
| 
 | |
| TWizard_mask::~TWizard_mask() 
 | |
| {
 | |
|   if (_reldesc)
 | |
|     delete _reldesc;
 | |
|   if (_rel)  
 | |
|     delete _rel;
 | |
| }           
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // Wizard main app
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TImport_wizard : public TSkeleton_application
 | |
| {      
 | |
| protected: // TSkeleton_application
 | |
|   virtual void main_loop();
 | |
| 
 | |
| public:
 | |
|   void import();
 | |
| };  
 | |
| 
 | |
| void TImport_wizard::import()
 | |
| {
 | |
|   const int nLogicNum = atoi(argv(2));
 | |
|   if (nLogicNum >= LF_USER)
 | |
|   {  
 | |
|     const TFilename strName = argv(3);
 | |
|     if (strName.exist())
 | |
|     {
 | |
|       TSystemisamfile file(nLogicNum);
 | |
|       file.load(strName);
 | |
|     }
 | |
|     else
 | |
|       error_box("Nome file errato: %s", (const char*)strName);
 | |
|   }
 | |
|   else
 | |
|     error_box("Numero file errato: %d", nLogicNum);
 | |
| }
 | |
| 
 | |
| void TImport_wizard::main_loop()
 | |
| { 
 | |
|   if (argc() < 3)
 | |
|   {
 | |
|     TWizard_mask m;
 | |
|     m.run();
 | |
|   }
 | |
|   else
 | |
|     import();
 | |
| }
 | |
| 
 | |
| int ba1800(int argc, char* argv[])
 | |
| {          
 | |
|   TImport_wizard of_oz;
 | |
|   of_oz.run(argc, argv, TR("Import Wizard"));
 | |
|   return 0;
 | |
| }
 |