Files correlati : ba1, ba2 Ricompilazione Demo : [ ] Commento : Aggiunte toolbar moderne ai programmi di installazione git-svn-id: svn://10.65.10.50/trunk@17359 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			2274 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2274 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <sys/stat.h>
 | ||
| 
 | ||
| #include <agasys.h>
 | ||
| #include <applicat.h>
 | ||
| #include <defmask.h>
 | ||
| #include <dongle.h>
 | ||
| #include <execp.h>
 | ||
| #include <files.h>
 | ||
| #include <golem.h>
 | ||
| #include <lffiles.h>
 | ||
| #include <msksheet.h>
 | ||
| #include <prefix.h>
 | ||
| #include <progind.h>
 | ||
| #include <text.h>
 | ||
| #include <sheet.h>
 | ||
| #include <utility.h>
 | ||
| #include <text.h>
 | ||
| 
 | ||
| #include "ba1.h"
 | ||
| #include "ba1600.h"
 | ||
| #include "ba1600a.h"
 | ||
| 
 | ||
| 
 | ||
| int find(const TString& name, TString_array & rows) ;
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Configurazione per installazione
 | ||
| ///////////////////////////////////////////////////////////
 | ||
|          
 | ||
| class TFascicolator_mask;         
 | ||
|          
 | ||
| class TCreazione_dischi : public TSkeleton_application
 | ||
| { 
 | ||
| protected:
 | ||
|   TFascicolator_mask* _mask;
 | ||
| 
 | ||
|   virtual bool use_files() const { return false; }
 | ||
|   virtual void main_loop();
 | ||
| public:
 | ||
|   virtual bool modify_mode() { return false; }
 | ||
|   TFascicolator_mask& mask() const { return *_mask; }
 | ||
| };
 | ||
| 
 | ||
| class TFascicolator : public TCreazione_dischi
 | ||
| { 
 | ||
| protected:
 | ||
|   virtual void main_loop();
 | ||
| 
 | ||
| public:
 | ||
|   virtual bool modify_mode() { return TRUE;}
 | ||
| };
 | ||
| 
 | ||
| inline TCreazione_dischi& app() { return (TCreazione_dischi&)main_app(); }
 | ||
| 
 | ||
| class TFconv_ini : public TConfig
 | ||
| {
 | ||
| public:         
 | ||
|   void export_module(const char* module, const char* summary);
 | ||
|   
 | ||
|   TFconv_ini(const char* path = "fconv.ini") : TConfig(path) { }
 | ||
|   virtual ~TFconv_ini() { }
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| // costruisce la lista del modulo e dei suoi sottomoduli interni
 | ||
| // vengono creati solo i sottomoduli che contengono almeno 
 | ||
| // una variabile di tipo File
 | ||
| int TInstall_ini::build_list(const TString& module, TString_array& a, 
 | ||
|                              const char* sommario, bool agg)
 | ||
| {            
 | ||
|   CHECKS(module.len() >= 2 || module[0]=='_', "Bad module ", (const char*)module);
 | ||
|   
 | ||
|   TConfig* sum = NULL;
 | ||
|   if (sommario && *sommario)
 | ||
|     sum = new TConfig(sommario, module);
 | ||
|   
 | ||
|   TAssoc_array vars;  
 | ||
|   TAuto_token_string tmp;
 | ||
|   TString paragraph;
 | ||
|   for (int sub = 0; sub <= 9; sub++)
 | ||
|   {
 | ||
|     paragraph = module;
 | ||
|     if (module[2] == '\0')     // Ho specificato un modulo principale
 | ||
|       paragraph << sub;
 | ||
|       
 | ||
|     bool reset_par=TRUE;
 | ||
|     vars.destroy();
 | ||
| 
 | ||
|     TAssoc_array& varlist = list_variables(paragraph);
 | ||
|     FOR_EACH_ASSOC_STRING(varlist, obj, key, str)
 | ||
|     {            
 | ||
|       const bool is_file = strncmp(key, "File", 4) == 0;
 | ||
|       tmp = str;     // Nome e aggiornamento
 | ||
|       // Quando creo il disco di aggiornamento salto tutti i file
 | ||
|       // che non hanno il flag di aggiornamento settato
 | ||
|       if (agg && is_file && tmp.get_char(1) != 'X')
 | ||
|         continue;
 | ||
|       if (sum) 
 | ||
|       {
 | ||
|         if (!is_file && reset_par)
 | ||
|           vars.add(key,tmp);
 | ||
|         else
 | ||
|         {
 | ||
|           if (reset_par)
 | ||
|           {
 | ||
|             reset_par=FALSE;
 | ||
|             sum->set_paragraph(paragraph);
 | ||
|             sum->remove_all();
 | ||
|             FOR_EACH_ASSOC_STRING(vars, obj, key, str)
 | ||
|               sum->set(key, str);
 | ||
|           }
 | ||
|           sum->set(key, tmp);
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       if (is_file)
 | ||
|       {
 | ||
|         tmp.add(paragraph, 2);              // Sottomodulo
 | ||
|         tmp.lower();  
 | ||
|         a.add(tmp);
 | ||
|       }  
 | ||
|     }  
 | ||
| 
 | ||
|     if (module[2] != '\0')
 | ||
|       break;
 | ||
|   }
 | ||
|   
 | ||
|   if (sum)
 | ||
|     delete sum;
 | ||
|   
 | ||
|   return a.items();
 | ||
| }
 | ||
| 
 | ||
| int TInstall_ini::build_complete_list(const TString& module, TString_array& a, 
 | ||
|                                       const char* sommario, bool agg)
 | ||
| {     
 | ||
|   if (sommario && *sommario)
 | ||
|   {
 | ||
|     TConfig sum(sommario, "Main");
 | ||
|     sum.set("Demo", demo() ? "X" : "");
 | ||
|   }
 | ||
|   // Lista dei file appartenenti ai sottomoduli del modulo principale (0-9)
 | ||
|   build_list(module, a, sommario, agg); 
 | ||
|   
 | ||
|   TString_array b;    //array locale temporaneo contenente la lista dei files da uccidere
 | ||
|   build_kill_list(module, b, sommario, agg);
 | ||
|   TAuto_token_string altri(get("Moduli", module));
 | ||
|   FOR_EACH_TOKEN(altri, mod)
 | ||
|   {
 | ||
|     const TString16 submodule = mod;
 | ||
|     // Lista dei files appartenenti ai sottomoduli esterni (moduli esclusi!)
 | ||
|     if (submodule.len() > 2)
 | ||
|       build_list(submodule, a, sommario, agg);
 | ||
|   }
 | ||
|   return a.items();
 | ||
| }
 | ||
| 
 | ||
| // costruisce la lista di programmi di gestione del modulo
 | ||
| int TInstall_ini::build_app_list(const TString& module, TString_array& a)
 | ||
| {
 | ||
|   TString paragraph;
 | ||
|   TToken_string row;
 | ||
|   for (int sub = 0; sub <= 9; sub++)
 | ||
|   {
 | ||
|     paragraph = module;
 | ||
|     if (module[2] == '\0')     // Ho specificato un modulo principale
 | ||
|       paragraph << sub;
 | ||
| 
 | ||
|     TAssoc_array& varlist = list_variables(paragraph);
 | ||
|     FOR_EACH_ASSOC_STRING(varlist, obj, key, str)
 | ||
|     {                                 
 | ||
|       int num;
 | ||
|       if (sscanf(key, "Edit_%d", &num) == 1)
 | ||
|       {
 | ||
|         row = "Edit";
 | ||
|         row.add(num);
 | ||
|         row.add(str);
 | ||
|         a.add(row);
 | ||
|       }
 | ||
|     }
 | ||
|     if (module[2] != '\0')
 | ||
|       break;
 | ||
|   }
 | ||
|   return a.items();
 | ||
| }
 | ||
| 
 | ||
| //crea x ogni modulo il sottomodulo 10 con i files da accoppare
 | ||
| int TInstall_ini::build_kill_list(const TString& module, TString_array& a, 
 | ||
|                              const char* sommario, bool agg)
 | ||
| {            
 | ||
|   CHECKS(module.len() >= 2, "Bad module ", (const char*)module);
 | ||
|   
 | ||
|   TString paragraph;
 | ||
|   paragraph << module << 99; 
 | ||
|   
 | ||
|   TConfig* sum = NULL;
 | ||
|   if (sommario && *sommario)
 | ||
|     sum = new TConfig(sommario, paragraph); //va nei sottomoduli 99
 | ||
|   
 | ||
|   TAuto_token_string tmp;     
 | ||
| 
 | ||
|   TAssoc_array& varlist = list_variables(paragraph);
 | ||
|   FOR_EACH_ASSOC_STRING(varlist, obj, key, str)
 | ||
|   {            
 | ||
|     const bool is_kill = strncmp(key, "Kill", 4) == 0;
 | ||
|     // Quando creo il disco di aggiornamento prendo solo i file che devono essere uccisi
 | ||
|     if (is_kill)
 | ||
|     {
 | ||
|       tmp = str;     // Nome e aggiornamento  
 | ||
| 
 | ||
|       if (agg && tmp.get_char(1) <= ' ')  //non e' selezionato
 | ||
|         continue;
 | ||
|       if (sum)
 | ||
|         sum->set(key, tmp);
 | ||
|       
 | ||
|       tmp.lower();
 | ||
|       a.add(tmp);
 | ||
|     }  
 | ||
|   }
 | ||
|   
 | ||
|   if (sum)
 | ||
|     delete sum;
 | ||
|   
 | ||
|   return a.items();
 | ||
| }
 | ||
| 
 | ||
| void TInstall_ini::export_paragraph(const char* module, const char* summary,const bool remove_old)
 | ||
| {                             
 | ||
|   CHECK(module && *module > ' ', "Can't export NULL module");
 | ||
|   CHECK(summary && *summary > ' ', "Can't export to NULL .ini");
 | ||
|   TInstall_ini sum(summary, module);     
 | ||
|   TString_array old_list;
 | ||
|   int last_file_num=0;
 | ||
|   const bool is_submodule=(module[2]!='\0');
 | ||
|   const int submodule=(module[2]-'0');
 | ||
|   TString4 main_module; main_module.strncpy(module,2);
 | ||
| 
 | ||
|   if (remove_old || !is_submodule )
 | ||
|   {
 | ||
|     // substitute...
 | ||
|     sum.remove_all();
 | ||
|   } 
 | ||
|   else 
 | ||
|   {
 | ||
|     // merge...
 | ||
|     sum.build_list(main_module, old_list);
 | ||
|     sum.set_paragraph(module);
 | ||
|     last_file_num=old_list.items();
 | ||
|   }
 | ||
| 
 | ||
|   TAssoc_array& ass = list_variables(module);
 | ||
|   TString newkey,tmps;
 | ||
|   TToken_string item_value;
 | ||
|   TString ;
 | ||
|   FOR_EACH_ASSOC_STRING(ass, obj, key, str)
 | ||
|   {
 | ||
|     if (!remove_old && is_submodule && strncmp(key, "File", 4)==0 )
 | ||
|     {
 | ||
|       // merging "File(X)" items...
 | ||
|       item_value=str;
 | ||
|       tmps=item_value.get(0);
 | ||
|       int item_number=find(tmps, old_list);
 | ||
|       if (item_number>=0)
 | ||
|       {
 | ||
|         // file sostituito
 | ||
|         TString old_smodule(old_list.row(item_number).get(2));
 | ||
|         TAssoc_array& oldvars = sum.list_variables(old_smodule);
 | ||
|         THash_object* obj;
 | ||
|         TToken_string oldvalue;
 | ||
|         oldvars.restart();
 | ||
|         do 
 | ||
|         {
 | ||
|           obj=oldvars.get_hashobj();
 | ||
|           oldvalue=((TString &)obj->obj());
 | ||
|           if (tmps == oldvalue.get(0))
 | ||
|             break;
 | ||
|         } 
 | ||
|         while (obj);
 | ||
|         newkey=obj->key();
 | ||
|         if (old_smodule!=module)
 | ||
|         {
 | ||
|           // devo cancellare il file dal vecchio sottomodulo
 | ||
|           sum.set_paragraph(old_smodule);
 | ||
|           sum.remove(newkey);
 | ||
|           sum.set_paragraph(module);
 | ||
|         } 
 | ||
|       } 
 | ||
|       else 
 | ||
|       {
 | ||
|         // nuovo file
 | ||
|         newkey = "File";
 | ||
|         newkey << '(' << last_file_num++ << ')';
 | ||
|       }
 | ||
|       sum.set(newkey, str);
 | ||
|     } 
 | ||
|     else 
 | ||
|     {
 | ||
|       sum.set(key, str);
 | ||
|     }
 | ||
|   }   
 | ||
| }   
 | ||
| 
 | ||
| void TInstall_ini::export_module_paragraphs(const char* module, const char* summary, const bool remove_old)
 | ||
| {           
 | ||
|   // esporta le info di composizione del modulo
 | ||
|   TString mod;
 | ||
|   for (int sub = -1; sub <= 9; sub++)
 | ||
|   {            
 | ||
|     mod = module;  
 | ||
|     if (sub >= 0) mod << sub;
 | ||
|     if (set_paragraph(mod))
 | ||
|       export_paragraph(mod, summary,remove_old);
 | ||
|   }
 | ||
|   // esporta la lista di eventuali files da eliminare (sono i killed)
 | ||
|   mod = module;  
 | ||
|   mod << 99;
 | ||
|   if (set_paragraph(mod))
 | ||
|     export_paragraph(mod, summary,remove_old);
 | ||
|   
 | ||
|   if (remove_old)
 | ||
|   {
 | ||
|     // esporta le info di conversione 
 | ||
|     TFilename path;
 | ||
|     TInstall_ini inst(summary);
 | ||
|     if (inst.name()==inst.default_name())
 | ||
|     {
 | ||
|       path = inst.name().path();
 | ||
|       path.add(module); path << "fconv.ini";
 | ||
|       TFconv_ini fconv(path); 
 | ||
|       fconv.export_module(module, "fconv.ini");
 | ||
|     }  
 | ||
|     else
 | ||
|     { 
 | ||
|       TFconv_ini fconv;
 | ||
|       path = inst.name().path();
 | ||
|       path.add(module); path << "fconv.ini";
 | ||
|       fconv.export_module(module, path);
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| const TString& TInstall_ini::version(const char* module)
 | ||
| { 
 | ||
|   CHECK(module && *module > ' ', "Can't get version of NULL module");
 | ||
|   const TString& ver = get("Versione", module);
 | ||
|   if (ver.empty() && strlen(module) > 2)
 | ||
|   {      
 | ||
|     TString16 str;
 | ||
|     str.strncpy(module, 2);
 | ||
|     return get("Versione", str);
 | ||
|   }
 | ||
|   return ver;
 | ||
| }
 | ||
| 
 | ||
| int TInstall_ini::patch(const char* module)
 | ||
| { 
 | ||
|   CHECK(module && *module > ' ', "Can't get version of NULL module");
 | ||
|   int patch = get_int("Patch", module);
 | ||
|   if (patch == 0 && strlen(module) > 2)
 | ||
|   {      
 | ||
|     TString16 str;
 | ||
|     str.strncpy(module, 2);
 | ||
|     patch = get_int("Patch", str);
 | ||
|   }
 | ||
|   return patch;
 | ||
| }
 | ||
| 
 | ||
| void TInstall_ini::version_info(const char* module,int& year, int& release,int& tag, int& patchlevel)
 | ||
| {
 | ||
|   TString ver = version(module);
 | ||
|   if (ver[0] == '9')
 | ||
|     ver.insert("19", 0);
 | ||
|   year = atoi(ver.left(4));   
 | ||
|   if (year == 0) 
 | ||
|     app().get_version_info(year, release, tag, patchlevel);
 | ||
|   else
 | ||
|   {  
 | ||
|     release = atoi(ver.mid(4,2));  
 | ||
|     if (release == 0) 
 | ||
|       release++;
 | ||
|     tag = atoi(ver.mid(6,2));  
 | ||
|     patchlevel = patch(module);
 | ||
|   }  
 | ||
| }
 | ||
| 
 | ||
| bool TInstall_ini::update_prices(const char* from)
 | ||
| {   
 | ||
|   CHECK(fexist(from), "Can't find listino prezzi");
 | ||
|   TConfig from_ini(from);
 | ||
|   from_ini.write_protect();
 | ||
|   const TDate curr_date(get("Listino","Main"));
 | ||
|   const TDate from_date(from_ini.get("Listino","Main"));
 | ||
|   if (from_date < curr_date)
 | ||
|     return FALSE;  
 | ||
|   set("Listino", from_date);
 | ||
|   
 | ||
|   TString_array modules; 
 | ||
|   from_ini.list_paragraphs(modules);
 | ||
|   FOR_EACH_ARRAY_ROW_BACK(modules, r, row) if (row->len() == 2)
 | ||
|   {
 | ||
|      TAssoc_array& prices = from_ini.list_variables(*row);
 | ||
|      set_paragraph(*row);
 | ||
|      FOR_EACH_ASSOC_STRING(prices, obj, key, str)
 | ||
|      {
 | ||
|         const TFixed_string price(key);
 | ||
|         if (price.compare("Prezzo", 6, TRUE) == 0)
 | ||
|           set(key, str);
 | ||
|      }
 | ||
|   } 
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| void TInstall_ini::prices(const char* module, word users, real& full, real& assist, bool correct_ass)
 | ||
| {
 | ||
|   real last_pac, last_ass;
 | ||
|   full = assist = 0.0;
 | ||
|   for (word u = 1; u <= users; u++)
 | ||
|   {                
 | ||
|     TAuto_token_string prezzi = get("Prezzo", module, int(u));
 | ||
|     if (prezzi.not_empty())
 | ||
|     {
 | ||
|       last_pac = prezzi.get(0); 
 | ||
|       if (last_pac < 50000.0) 
 | ||
|         last_pac *= 1000.0;
 | ||
|       last_ass = prezzi.get(); 
 | ||
|       if (last_ass < 50000.0) 
 | ||
|         last_ass *= 1000.0;
 | ||
|       const int mese = TDate(TODAY).month();
 | ||
|       last_ass = last_ass * (correct_ass ? (12-mese) / 12 : 1);
 | ||
|       last_ass.round(-3);
 | ||
|     }
 | ||
|     full += last_pac;
 | ||
|     assist += last_ass;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TFconv_ini
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| void TFconv_ini::export_module(const char* module, const char* summary)
 | ||
| {        
 | ||
|   TString_array paragraphs;
 | ||
|   list_paragraphs(paragraphs);
 | ||
| 
 | ||
|   if (paragraphs.items() > 0)   //solo se c'e' qualcosa nel file conv deve creare XXfconv
 | ||
|   {
 | ||
|     paragraphs.sort();
 | ||
|     
 | ||
|     TConfig sommario(summary);
 | ||
|     const word module_code = dongle().module_name2code(module);
 | ||
|     FOR_EACH_ARRAY_ROW(paragraphs, p, para)
 | ||
|     {
 | ||
|       TAssoc_array& variables = list_variables(*para);
 | ||
|       FOR_EACH_ASSOC_STRING(variables, obj, key, str)
 | ||
|       {
 | ||
|         const char* parenthesis = strchr(key, '(');
 | ||
|         if (parenthesis)
 | ||
|         {
 | ||
|           const int logic_num = atoi(parenthesis+1);
 | ||
|           if (logic_num > 0)
 | ||
|           {
 | ||
|             TDir dirinfo; dirinfo.get(logic_num);
 | ||
|             const long flags = dirinfo.flags() % 10000;
 | ||
|             if (flags == module_code)
 | ||
|               sommario.set(key, str, module);
 | ||
|           }    
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Maschera composizione del modulo
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TMod_composition_msk : public TMask
 | ||
| { 
 | ||
| protected:
 | ||
|   static bool sheet_notify(TSheet_field& sf, int row, KEY key);
 | ||
|   static bool missing_notify(TSheet_field& sf, int row, KEY key);
 | ||
|   bool kill_missing(const char* name, bool update);
 | ||
|   static bool link_handler(TMask_field& f, KEY k);  
 | ||
| 
 | ||
|   static bool kill_notify(TSheet_field& sf, int row, KEY key); //metodo per la gestione della lista dei files da eliminare effettivamente
 | ||
|   static bool obsolete_notify(TSheet_field& sf, int row, KEY key);   //metodo x riempire la lista dei files che si consiglia di eliminare
 | ||
|   bool kill_obsolete(const char* name, bool update);  //metodi x eliminare i files dalla lista dei consigliati quando si aggiungono
 | ||
|   static bool obs_handler(TMask_field& f, KEY k);     //alla lista definitiva di eliminazione
 | ||
|                                                         
 | ||
|   static bool file_handler(TMask_field& f, KEY k);
 | ||
|   static bool edit_handler(TMask_field& f, KEY k);
 | ||
|   static bool deselect_handler(TMask_field& f, KEY k);
 | ||
|   static bool isam_handler(TMask_field& f, KEY k);
 | ||
|   static bool kill_handler(TMask_field& f, KEY k);
 | ||
|    
 | ||
| public:
 | ||
|   void load(const TString& module);
 | ||
|   void save();
 | ||
| 
 | ||
|   TMod_composition_msk(const bool modify_mode=FALSE);
 | ||
|   virtual ~TMod_composition_msk() { }
 | ||
| };
 | ||
| 
 | ||
| // Toglie il file dallo sheet dei mancanti
 | ||
| bool TMod_composition_msk::kill_missing(const char* name, bool update)
 | ||
| {
 | ||
|   TSheet_field& miss = sfield(F_MISSING);
 | ||
|   FOR_EACH_SHEET_ROW_BACK(miss, r, row)
 | ||
|   {
 | ||
|     if (row->compare(name, -1, TRUE) == 0)
 | ||
|     {
 | ||
|       miss.destroy(r, update);
 | ||
|       break;
 | ||
|     }
 | ||
|   }
 | ||
|   return r >= 0;
 | ||
| }
 | ||
| 
 | ||
| // Toglie il file dallo sheet degli ELIMINABILI
 | ||
| bool TMod_composition_msk::kill_obsolete(const char* name, bool update)
 | ||
| {
 | ||
|   TSheet_field& obs = sfield(F_OBSOLETE);
 | ||
|   FOR_EACH_SHEET_ROW_BACK(obs, r, row)
 | ||
|   {
 | ||
|     if (row->compare(name, -1, TRUE) == 0)
 | ||
|     {
 | ||
|       obs.destroy(r, update);
 | ||
|       break;
 | ||
|     }
 | ||
|   }
 | ||
|   return r >= 0;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::sheet_notify(TSheet_field& sf, int r, KEY key)
 | ||
| {           
 | ||
|   bool ok = TRUE;
 | ||
|   switch(key)
 | ||
|   {
 | ||
|   case K_TAB:
 | ||
|     // Posso cancellare solo le righe abilitate
 | ||
|     sf.sheet_mask().enable(DLG_DELREC, !sf.cell_disabled(r, 1));
 | ||
|     break;
 | ||
|   case K_ENTER:
 | ||
|     {
 | ||
|       TFilename mask = sf.row(r).get(0);
 | ||
|       if (mask.find('*') >= 0 || mask.find('?') >= 0)
 | ||
|       {
 | ||
|         TString_array arr; list_files(mask, arr);
 | ||
|         const int items = arr.items();
 | ||
|         
 | ||
|         if (items > 0)
 | ||
|         {
 | ||
|           TMod_composition_msk& msk = (TMod_composition_msk&)sf.mask();
 | ||
|           TString_array & rows=msk.sfield(F_SHEET).rows_array();
 | ||
| 
 | ||
|           TString16 module = sf.row(r).get(2);
 | ||
|           if (module.len() < 3)
 | ||
|             module << msk.get(F_MODULE) << '1';
 | ||
|         
 | ||
|           TFilename start;
 | ||
|           DIRECTORY dir; xvt_fsys_get_dir(&dir);
 | ||
|           xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size());
 | ||
|           const int maxlen = start.len();
 | ||
|           
 | ||
|           bool found = FALSE;
 | ||
|           for (int i = 0; i < items; i++)
 | ||
|           {               
 | ||
|             TString& file = arr.row(i);
 | ||
|             if (file.compare(start, maxlen, TRUE) == 0)
 | ||
|               file.ltrim(maxlen+1);
 | ||
|             file.lower();
 | ||
|             
 | ||
|             msk.kill_missing(file, FALSE);
 | ||
|             
 | ||
|             if (::find(file,rows)>=0)
 | ||
|             {
 | ||
|               TToken_string& row = sf.row(found ? -1 : r);
 | ||
|               row = file;
 | ||
|               row.add(" ");
 | ||
|               row.add(module);
 | ||
|               found = TRUE;
 | ||
|             }  
 | ||
|           }
 | ||
|           // Se ne ho trovato almeno uno valido allora updato
 | ||
|           if (found)
 | ||
|           {
 | ||
|             sf.force_update();
 | ||
|             TSheet_field& miss = msk.sfield(F_MISSING);
 | ||
|             miss.force_update();
 | ||
|           }  
 | ||
|         }
 | ||
|         else
 | ||
|           ok = sf.error_box(FR("Nessun file corrisponde a %s"), mask.get_buffer());
 | ||
|       }
 | ||
|     }  
 | ||
|     break;
 | ||
|   case K_DEL:
 | ||
|     ok = !sf.cell_disabled(r, 1);
 | ||
|     if (ok)
 | ||
|     {
 | ||
|       // Sposto la riga cancellata nello sheet a fianco
 | ||
|       TSheet_field& miss = sf.mask().sfield(F_MISSING);
 | ||
|       miss.row(-1) = sf.row(r).get(0);
 | ||
|       miss.force_update();
 | ||
|     }
 | ||
|     break;
 | ||
|   case K_CTRL+K_INS:  
 | ||
|     { 
 | ||
|       // Propongo il sottomodulo automaticamente in inserimento
 | ||
|       TString16 module;
 | ||
|       module << sf.mask().get(F_MODULE) << '1';
 | ||
|       
 | ||
|       TToken_string& row = sf.row(r);
 | ||
|       row.add(module, 2);
 | ||
|     }
 | ||
|     break;
 | ||
|   default: 
 | ||
|     break;   
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| //metodo per la gestione dello sheet con la lista dei files da ELIMINARE effettivamente
 | ||
| bool TMod_composition_msk::kill_notify(TSheet_field& sf, int r, KEY key)
 | ||
| {
 | ||
|   bool ok = TRUE;
 | ||
|   switch(key)
 | ||
|   {
 | ||
|   case K_TAB:
 | ||
|     // Posso cancellare solo le righe abilitate
 | ||
|     sf.sheet_mask().enable(DLG_DELREC, !sf.cell_disabled(r, 1));
 | ||
|     break;
 | ||
|   case K_ENTER:
 | ||
|     {
 | ||
|       TFilename mask = sf.row(r).get(0);
 | ||
|       if (mask.find('*') >= 0 || mask.find('?') >= 0)
 | ||
|       {
 | ||
|         TString_array arr; list_files(mask, arr);
 | ||
|         const int items = arr.items();
 | ||
|         
 | ||
|         if (items > 0)
 | ||
|         {
 | ||
|           TMod_composition_msk& msk = (TMod_composition_msk&)sf.mask();
 | ||
|           TString_array & rows=msk.sfield(F_KILL).rows_array();
 | ||
|         
 | ||
|           TFilename start;
 | ||
|           DIRECTORY dir; xvt_fsys_get_dir(&dir);
 | ||
|           xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size());
 | ||
|           const int maxlen = start.len();
 | ||
|           
 | ||
|           bool found = FALSE;
 | ||
|           for (int i = 0; i < items; i++)
 | ||
|           {               
 | ||
|             TString& file = arr.row(i);
 | ||
|             if (file.compare(start, maxlen, TRUE) == 0)
 | ||
|               file.ltrim(maxlen+1);
 | ||
|             file.lower();
 | ||
|             
 | ||
|             msk.kill_obsolete(file, FALSE);
 | ||
|             
 | ||
|             if (::find(file,rows)>=0)
 | ||
|             {
 | ||
|               TToken_string& row = sf.row(found ? -1 : r);
 | ||
|               row = file;
 | ||
|               row.add(" ");
 | ||
|               found = TRUE;
 | ||
|             }  
 | ||
|           }
 | ||
|           // Se ne ho trovato almeno uno valido allora updato
 | ||
|           if (found)
 | ||
|           {
 | ||
|             sf.force_update();
 | ||
|             TSheet_field& miss = msk.sfield(F_OBSOLETE);
 | ||
|             miss.force_update();
 | ||
|           }  
 | ||
|         }
 | ||
|         else
 | ||
|           ok = sf.error_box("Nessun file corrisponde a %s", mask.get_buffer());
 | ||
|       }
 | ||
|     }  
 | ||
|     break;
 | ||
|   case K_DEL:
 | ||
|     ok = !sf.cell_disabled(r, 1);
 | ||
|     if (ok)
 | ||
|     {
 | ||
|       // Sposto la riga cancellata nello sheet a fianco
 | ||
|       TSheet_field& miss = sf.mask().sfield(F_OBSOLETE);
 | ||
|       miss.row(-1) = sf.row(r).get(0);
 | ||
|       miss.force_update();
 | ||
|     }
 | ||
|     break;
 | ||
|   default: 
 | ||
|     break;   
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::missing_notify(TSheet_field& sf, int r, KEY key)
 | ||
| {           
 | ||
|   bool ok = TRUE;
 | ||
|   if (key == K_INS)
 | ||
|   {   
 | ||
|     // Sposto tutte le righe nello spreadsheet a fianco
 | ||
|     TMask& mainmask = sf.mask();
 | ||
|     TSheet_field& sheet = mainmask.sfield(F_SHEET);
 | ||
| 
 | ||
|     FOR_EACH_SHEET_ROW(sf, idx, riga)
 | ||
|     {
 | ||
|       TToken_string& newrow = sheet.row(-1);
 | ||
|       newrow = *riga;
 | ||
|       TString16 submod = newrow.left(2);
 | ||
|       submod << '1';
 | ||
|       newrow.add(submod, 2);
 | ||
|     } 
 | ||
| 
 | ||
|     sf.destroy();
 | ||
|     sf.force_update();
 | ||
|     sheet.force_update();
 | ||
|     ok = FALSE;
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::file_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_F9)
 | ||
|   {                        
 | ||
|     DIRECTORY dir; xvt_fsys_get_dir(&dir);
 | ||
| 
 | ||
|     FILE_SPEC fs;
 | ||
|     xvt_fsys_convert_str_to_fspec("*.*", &fs);
 | ||
|     fs.dir = dir;
 | ||
|     
 | ||
|     FL_STATUS ok = xvt_dm_post_file_open(&fs, TR("Selezionare il file ..."));
 | ||
|     xvt_fsys_set_dir(&dir);
 | ||
| 
 | ||
|     if (ok == FL_OK)
 | ||
|     {
 | ||
|       TFilename file, start;
 | ||
|       xvt_fsys_convert_dir_to_str(&fs.dir, file.get_buffer(), file.size());
 | ||
|       xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size());
 | ||
| 
 | ||
|       const int maxlen = start.len();
 | ||
|       if (file.compare(start, maxlen, TRUE) == 0)
 | ||
|       {
 | ||
|         file.ltrim(maxlen+1);
 | ||
|         file.add(fs.name); 
 | ||
|         file.ext(fs.type);
 | ||
|         f.set(file);    
 | ||
|         k = K_TAB;
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         return f.error_box(FR("Il file deve trovarsi nel percorso %s"), 
 | ||
|                            start.get_buffer());
 | ||
|       }  
 | ||
|     }
 | ||
|   }
 | ||
|     
 | ||
|   if (k = K_TAB && f.focusdirty())
 | ||
|   {
 | ||
|     TMod_composition_msk& msk = (TMod_composition_msk&)f.mask().get_sheet()->mask();
 | ||
|     msk.kill_missing(f.get(), TRUE);
 | ||
|   }
 | ||
|   
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::kill_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k = K_TAB && f.focusdirty())
 | ||
|   {
 | ||
|     TMod_composition_msk& msk = (TMod_composition_msk&)f.mask().get_sheet()->mask();
 | ||
|     msk.kill_obsolete(f.get(), TRUE);
 | ||
|   }
 | ||
|   
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::edit_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {
 | ||
|     TFilename file = f.mask().get(101);
 | ||
|     if (xvt_str_compare_ignoring_case(file.ext(), "exe") == 0)
 | ||
|     {                         
 | ||
|       file << " -0";
 | ||
|       TExternal_app app(file);
 | ||
|       app.run();
 | ||
|     }
 | ||
|     else
 | ||
|       ::edit_url(file);
 | ||
|   }  
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::link_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {
 | ||
|     TMask& modmask = f.mask();
 | ||
|     TSheet_field* sf = modmask.get_sheet();
 | ||
|     TMask& mainmask = sf->mask();
 | ||
|     TSheet_field& sheet = mainmask.sfield(F_SHEET);
 | ||
|     TToken_string& newrow = sheet.row(-1);
 | ||
|     newrow = modmask.get(101);          // Nome del file
 | ||
|     newrow.add(" ");                    // Non e' nell'aggiornamento
 | ||
|     newrow.add(mainmask.get(F_MODULE)); // Modulo attuale
 | ||
|     newrow << '1';                      // Sottomodulo standard
 | ||
|     if (modmask.is_running())
 | ||
|     {
 | ||
|       modmask.stop_run(K_ESC);
 | ||
|       do_events();
 | ||
|     }  
 | ||
|     sf->destroy(sf->selected());
 | ||
|     sheet.force_update();  
 | ||
|     sf->force_update();
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }  
 | ||
| 
 | ||
| static int obsolete_found(TConfig& cfg, void* jolly)
 | ||
| {
 | ||
|   TAssoc_array& list = cfg.list_variables(); 
 | ||
|   TString_array& files = *(TString_array*)jolly; //castato jolly a TString_array; sono i files su disco
 | ||
|   FOR_EACH_ASSOC_STRING(list, hash, key, string)
 | ||
|   {
 | ||
|     if (strncmp(key, "File(", 5) == 0)
 | ||
|     { 
 | ||
|       int pos = files.find(string);
 | ||
|       if (pos >=0)
 | ||
|         files.destroy(pos, TRUE); //se trova il file sia su disco che nell'ini -> lo toglie dall'elenco su disco
 | ||
|     }
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| // metodo per riempire lo sheet dei file che si CONSIGLIA di eliminare
 | ||
| bool TMod_composition_msk::obsolete_notify(TSheet_field& sf, int r, KEY key)
 | ||
| { 
 | ||
|   if (key == K_INS) //la compilazione dello sheet avviene solo quando si preme il pulsante +
 | ||
|   { 
 | ||
|     TWait_cursor hourglass;
 | ||
|     TString_array& elenco_dir = sf.rows_array();  //string_array che conterra' i files della directory
 | ||
|     elenco_dir.destroy();                         //resetta l'elenco dei files della directory
 | ||
|     list_files("*.*", elenco_dir);                //legge tutti i files della dir corrente e li mette in elenco_dir
 | ||
|     FOR_EACH_ARRAY_ROW(elenco_dir,i,row)          //mette in minuscolo tutti i nomi di files su disco
 | ||
|       row->lower();
 | ||
|                                                   //e' il file install.ini
 | ||
|     TInstall_ini ini;
 | ||
|     ini.for_each_paragraph(obsolete_found, &elenco_dir);  //per ogni paragrafo dell'install.ini chiama la obsolete_found
 | ||
|     sf.force_update();                            //aggiornamento dello sheet (di sinistra) sulla maschera
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| //spostamento oggetti da sheet obsoleti a sheet con files da eliminare (sulla mask e' da destra a sinistra)
 | ||
| bool TMod_composition_msk::obs_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {
 | ||
|     TMask& modmask = f.mask();              //maschera di riga dello sheet
 | ||
|     TSheet_field* sf = modmask.get_sheet();    
 | ||
|     TMask& mainmask = sf->mask();
 | ||
|     TSheet_field& sheet = mainmask.sfield(F_KILL);  //sheet sinistro della maschera di Eliminazione
 | ||
|     TToken_string& newrow = sheet.row(-1);          //aggiunge una riga allo sheet...
 | ||
|     newrow = modmask.get(101);          //..e ci mette il nome del file
 | ||
| 
 | ||
|     if (modmask.is_running())
 | ||
|     {
 | ||
|       modmask.stop_run(K_ESC);
 | ||
|       do_events();
 | ||
|     }  
 | ||
|     sf->destroy(sf->selected());
 | ||
|     sheet.force_update();     //update dello sheet sinistro della maschera di eliminazione (files condannati)
 | ||
|     sf->force_update();
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| bool TMod_composition_msk::deselect_handler(TMask_field& f, KEY k)
 | ||
| {                          
 | ||
|   if (k == K_SPACE)
 | ||
|   {           
 | ||
|     TSheet_field& sheet = f.mask().sfield(F_SHEET);
 | ||
|     FOR_EACH_SHEET_ROW_BACK(sheet, r, row)
 | ||
|       row->add(" ", 1);
 | ||
|     sheet.force_update();  
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TMod_composition_msk::isam_handler(TMask_field& f, KEY k)
 | ||
| {                          
 | ||
|   if (k == K_F9)
 | ||
|   {
 | ||
|     TMask& m = f.mask();
 | ||
|     TArray_sheet sht(-1,-1,-4,-4,TR("Selezione archivio"), HR("Codice@6R|Descrizione archivio@70"));
 | ||
|     const TPrefix& pref = prefix();
 | ||
|     const int total = pref.items();
 | ||
|     if (total > 0)
 | ||
|     {
 | ||
|       TWait_cursor hourglass;
 | ||
|       for (int i = LF_USER; i < total; i++)
 | ||
|       {
 | ||
|         TToken_string* row = new TToken_string;
 | ||
|         *row << i;
 | ||
|         row->add(pref.description(*row));
 | ||
|         sht.rows_array().add(row);
 | ||
|       }
 | ||
|       sht.select(m.get_int(f.dlg()) - LF_USER);
 | ||
|     }
 | ||
|     if (sht.run() == K_ENTER)
 | ||
|       m.set(f.dlg(), sht.selected() + LF_USER);
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| static int file_compare(const TObject** o1, const TObject** o2)
 | ||
| {
 | ||
|   TToken_string* r1 = (TToken_string*)*o1;
 | ||
|   TToken_string* r2 = (TToken_string*)*o2;
 | ||
|   
 | ||
|   int cmp = xvt_str_compare_ignoring_case(r1->get(-2), r2->get(-2));
 | ||
|   if (cmp == 0)
 | ||
|     cmp = xvt_str_compare_ignoring_case(*r1, *r2);
 | ||
|   return cmp;  
 | ||
| }
 | ||
| 
 | ||
| void TMod_composition_msk::load(const TString& module)
 | ||
| {                 
 | ||
|   TWait_cursor hourglass;
 | ||
|   set(F_MODULE, module);
 | ||
| 
 | ||
|   TInstall_ini ini;                             //install.ini
 | ||
|   
 | ||
|   TSheet_field& s = sfield(F_SHEET);            //legge da install.ini la lista dei files del modulo
 | ||
|   ini.build_list(module, s.rows_array());
 | ||
|   s.rows_array().TArray::sort(file_compare);
 | ||
|   
 | ||
|   TSheet_field& p = sfield(F_PROGRAMS);         //la lista dei programmi tipo quelli x l'editing
 | ||
|   ini.build_app_list(module, p.rows_array());
 | ||
| 
 | ||
|   TFilename mask; 
 | ||
|   mask << module << "*.*";                    
 | ||
|   
 | ||
|   TSheet_field& miss = sfield(F_MISSING);
 | ||
|   TString_array& arr = miss.rows_array();
 | ||
|   list_files(mask, arr);
 | ||
|   
 | ||
|   TSheet_field& kill = sfield(F_KILL);         //legge da install.ini la lista dei files da uccidere
 | ||
|   ini.build_kill_list(module, kill.rows_array());
 | ||
| 
 | ||
|   const char* bad_ext[] = { "bsc", "mak", "obj", "pdb", "rc", 
 | ||
|                             "res", "sbr", "vcw", "wsp", NULL };
 | ||
|   
 | ||
|   FOR_EACH_ARRAY_ROW_BACK(arr, index, row)
 | ||
|   { 
 | ||
|     mask = *row;   
 | ||
|     mask.lower();
 | ||
|     const TString16 ext = mask.ext();
 | ||
| 
 | ||
|     bool ok = TRUE;
 | ||
|     for (int e = 0; bad_ext[e]; e++)
 | ||
|     {
 | ||
|       if (ext == bad_ext[e])
 | ||
|       {
 | ||
|         ok = FALSE;
 | ||
|         break;
 | ||
|       }  
 | ||
|     }
 | ||
|     
 | ||
|     if (ok)
 | ||
|     {
 | ||
|       FOR_EACH_SHEET_ROW_BACK(s, i, row)
 | ||
|       {
 | ||
|         if (mask.compare(row->get(0), -1, TRUE) == 0)
 | ||
|           break;
 | ||
|       }   
 | ||
|       ok = i < 0;
 | ||
|     }  
 | ||
|     
 | ||
|     if (ok)
 | ||
|       arr.row(index) = mask;
 | ||
|     else
 | ||
|       arr.destroy(index);
 | ||
|   }       
 | ||
|   arr.sort();
 | ||
| }
 | ||
| 
 | ||
| void TMod_composition_msk::save()
 | ||
| {                      
 | ||
|   TWait_cursor hourglass;
 | ||
|   TSheet_field& sheet = sfield(F_SHEET);
 | ||
| 
 | ||
|   TInstall_ini ini;
 | ||
|   int index;       
 | ||
|   
 | ||
|   const TString module = get(F_MODULE);
 | ||
|   const TString version = ini.version(module);
 | ||
|   const long patch = ini.patch(module);
 | ||
|   
 | ||
|   for (index = 0; index <= 9; index++)
 | ||
|   {
 | ||
|     TString16 sub; sub << module << index;
 | ||
|     if (ini.set_paragraph(sub))
 | ||
|       ini.remove_all();
 | ||
|   }
 | ||
| 
 | ||
|   TToken_string tmp;    
 | ||
|   index = 0;
 | ||
|   
 | ||
|   FOR_EACH_SHEET_ROW(sheet, r, row)
 | ||
|   {
 | ||
|     TString16 sub = row->get(2);
 | ||
|     if (sub.blank())
 | ||
|       sub << module << '1';
 | ||
|     else
 | ||
|     {  
 | ||
|       if (isdigit(sub[0]) && sub[1]=='\0')
 | ||
|       {
 | ||
|         sub.insert(module, 0);
 | ||
|         sub.cut(3);
 | ||
|       }  
 | ||
|     }   
 | ||
|     if (sub.left(2) == module)
 | ||
|     {
 | ||
|       tmp = row->get(0);       // Nome del file
 | ||
|       const bool agg = row->get_char() > ' ';
 | ||
|       if (agg) tmp.add("X");   // Flag aggiornamento
 | ||
|       ini.set("File", tmp, sub, TRUE, index++);
 | ||
|       ini.set("Versione", version); // Aggiorna versione del sottomodulo
 | ||
|       ini.set("Patch", patch);
 | ||
|     }
 | ||
|   }
 | ||
|   
 | ||
|   TSheet_field& sp = sfield(F_PROGRAMS);
 | ||
|   FOR_EACH_SHEET_ROW(sp, pr, prow)
 | ||
|   {                 
 | ||
|     TString16 var = prow->get(0);
 | ||
|     var <<  '_' << prow->get(1);
 | ||
|     
 | ||
|     TFilename n(prow->get(2));
 | ||
|     const int spc = n.find(' ');
 | ||
|     if (spc >= 0) n.cut(spc);
 | ||
|     n.ext("exe");
 | ||
|     TString16 sub = module;                
 | ||
|     FOR_EACH_SHEET_ROW(sheet, sr, srow)
 | ||
|     {
 | ||
|       if (n == srow->get(0))
 | ||
|       {
 | ||
|         sub = srow->get(2);
 | ||
|         break;
 | ||
|       }
 | ||
|     }
 | ||
|     n = prow->get(2);
 | ||
|     ini.set(var, n, sub);
 | ||
|   }
 | ||
|   
 | ||
|   TSheet_field& kp = sfield(F_KILL);
 | ||
|   TString16 sub = module;
 | ||
|   sub << 99;  
 | ||
|   FOR_EACH_SHEET_ROW(kp, kr, krow)
 | ||
|   {    
 | ||
|     ini.set("Kill", *krow, sub, TRUE, kr);
 | ||
|   }
 | ||
|   
 | ||
| }
 | ||
| 
 | ||
| TMod_composition_msk::TMod_composition_msk(const bool modify_mode)
 | ||
|                     : TMask("ba1600b")
 | ||
| {                
 | ||
|   TSheet_field& s = sfield(F_SHEET);
 | ||
|   TSheet_field& miss = sfield(F_MISSING);
 | ||
|   TSheet_field& prog = sfield(F_PROGRAMS);
 | ||
|   TSheet_field& kill = sfield(F_KILL);  
 | ||
|   TSheet_field& obs = sfield(F_OBSOLETE);
 | ||
|   set_handler(F_DESELECT, deselect_handler);
 | ||
|   if (modify_mode)
 | ||
|   {
 | ||
|     s.set_notify(sheet_notify);
 | ||
|     s.sheet_mask().set_handler(S_FILE, file_handler);
 | ||
|     s.sheet_mask().set_handler(DLG_EDIT, edit_handler);
 | ||
|     miss.disable();   // Read-only sheet
 | ||
|     miss.set_notify(missing_notify);
 | ||
|     miss.sheet_mask().set_handler(100, link_handler);
 | ||
|     prog.sheet_mask().set_handler(102, isam_handler);
 | ||
|     
 | ||
|     obs.set_notify(obsolete_notify);
 | ||
|     obs.sheet_mask().set_handler(100, obs_handler);
 | ||
|     
 | ||
|     kill.set_notify(kill_notify);
 | ||
|     kill.sheet_mask().set_handler(101, kill_handler);
 | ||
|   } 
 | ||
|   else 
 | ||
|   {
 | ||
|     s.disable();   // Read-only sheet
 | ||
| 
 | ||
|     miss.hide();   
 | ||
|     disable_page(1);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Maschera del modulo
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TModule_mask : public TMask
 | ||
| { 
 | ||
|   bool _dirty_composition;
 | ||
|   bool module_dependent(int row, TString_array &p_submodules, TString &sub_mod, TString &ver, int & patch) const ;
 | ||
| 
 | ||
| public:
 | ||
|   bool list_is_dirty() const { return _dirty_composition;}
 | ||
|   void dirty_composition(bool val = TRUE) { _dirty_composition = val; }
 | ||
|   bool check_patchlevels(TMod_composition_msk &mm);
 | ||
|   virtual ~TModule_mask() {}
 | ||
| };
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Maschera principale
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TCreadischi_mask : public TMask
 | ||
| { 
 | ||
| protected:    
 | ||
|   static bool list_handler(TMask_field& f, KEY k);
 | ||
|   static bool confirm_handler(TMask_field& f, KEY k);
 | ||
|   static bool creazip_handler(TMask_field& f, KEY k);
 | ||
|   static bool testpatch_handler(TMask_field& f, KEY k);
 | ||
|   static bool why_handler(TMask_field& f, KEY k);
 | ||
|   static bool modules_notify(TSheet_field& f, int row, KEY k);
 | ||
|   static bool import_export_handler(TMask_field& f, KEY k);
 | ||
|   static bool patchl_handler(TMask_field& f, KEY k);
 | ||
| 
 | ||
| 
 | ||
|   virtual const TFilename& build_export_path(TFilename& path) const;
 | ||
| 
 | ||
|   virtual bool zip_file(const char* archive, const char* file) const;
 | ||
|   virtual int  split_file(const TFilename& file, size_t size) const;
 | ||
|   virtual bool move_file(const TFilename& file, const char* dir) const;
 | ||
|   virtual bool zip_module(const TString& module, bool agg, int patch_level) const;
 | ||
| 
 | ||
|   virtual bool set_version_info(const TFilename& filename, 
 | ||
|                         TInstall_ini& ini, const char* module) const;
 | ||
|   
 | ||
|   virtual bool show_all_modules() {return FALSE;}
 | ||
| public:
 | ||
|   virtual void save();
 | ||
|   virtual void load();
 | ||
| 
 | ||
|   TCreadischi_mask();
 | ||
|   virtual ~TCreadischi_mask() { }
 | ||
| };
 | ||
| 
 | ||
| class TFascicolator_mask : public TCreadischi_mask
 | ||
| { 
 | ||
|   long find_signature(const TFilename& filename, const char* signature) const;
 | ||
| 
 | ||
| protected:    
 | ||
|   static bool list_handler(TMask_field& f, KEY k);
 | ||
|   static bool confirm_handler(TMask_field& f, KEY k);
 | ||
|   static bool creazip_handler(TMask_field& f, KEY k);
 | ||
| 
 | ||
|   static bool patchl_handler(TMask_field& f, KEY k);
 | ||
|   
 | ||
|   // fuinzioni per la "firma"  del file con il numero di release
 | ||
|   virtual bool set_version_info(const TFilename& filename, 
 | ||
|                         TInstall_ini& ini, const char* module) const;
 | ||
|        
 | ||
|   virtual bool show_all_modules() {return TRUE;}
 | ||
| public:
 | ||
|   virtual void save();
 | ||
| 
 | ||
|   TFascicolator_mask();
 | ||
|   virtual ~TFascicolator_mask() { }
 | ||
| };
 | ||
|                                      
 | ||
| 
 | ||
| bool TCreadischi_mask::modules_notify(TSheet_field& f, int row, KEY k)
 | ||
| {          
 | ||
|   bool ok = TRUE;
 | ||
|   if (k == K_INS || k == K_DEL)
 | ||
|     ok = FALSE;
 | ||
|   if (k == K_TAB)
 | ||
|   {
 | ||
|     TModule_mask &mm =(TModule_mask &)f.sheet_mask();
 | ||
|     mm.dirty_composition(FALSE);
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| // controlla se il modulo in curr_row dipende da uno dei sottomoduli nell'array p_submodules
 | ||
| // e ne restituisce :
 | ||
| //TString16 &sub_mod, : il codice del (primo) sottomodulo da cui dipende
 | ||
| //TString16 &ver,     : la propria versione 
 | ||
| //int & patch         : la propria patchlevel
 | ||
| bool TModule_mask::module_dependent(int rownum, TString_array &p_submodules, TString &sub_mod, TString &ver, int & patch) const 
 | ||
| {
 | ||
|   TSheet_field& modsheet = get_sheet()->mask().sfield(F_SHEET);
 | ||
|   TToken_string& curr_row=modsheet.row(rownum);
 | ||
|   TAuto_token_string ext_mod=curr_row.get(modsheet.cid2index(S_EXTERN));
 | ||
|   const int smods = ext_mod.blank() ? 0 : ext_mod.items() ;
 | ||
|   for (int c=0; c < smods; c++)
 | ||
|   {
 | ||
|     // is an external SUB module ?
 | ||
|     sub_mod = ext_mod.get(c);
 | ||
|     if (sub_mod[2]!='\0' )
 | ||
|     {
 | ||
|       // check patched submodules
 | ||
|       const int pmods = p_submodules.items();
 | ||
|       for (int p=0; p < pmods; p++)
 | ||
|       {
 | ||
|         if (p_submodules.row(p) == sub_mod)
 | ||
|         {
 | ||
|           ver=curr_row.get(modsheet.cid2index(S_VERSION));
 | ||
|           patch=atoi(curr_row.get(modsheet.cid2index(S_PATCHLEVEL)));
 | ||
|           return TRUE;
 | ||
|         }
 | ||
|       } // loop over patched modules
 | ||
|     }
 | ||
|   } // loop over external modules
 | ||
|   return FALSE;
 | ||
| }
 | ||
| 
 | ||
| bool TModule_mask::check_patchlevels( TMod_composition_msk &mm)
 | ||
| {
 | ||
|   const TString& module = get(S_MODULE);
 | ||
|   const TString& version =get(S_VERSION);
 | ||
|   const int patchlev = get_int(S_PATCHLEVEL);
 | ||
| 
 | ||
|   // crea la lista dei sottomoduli 
 | ||
|   TSheet_field& sf = mm.sfield(F_SHEET);
 | ||
|   TString_array patched_submodules,submodules;
 | ||
|   FOR_EACH_SHEET_ROW(sf, idx, riga)
 | ||
|   {
 | ||
|     TToken_string& curr_row=sf.row(idx);
 | ||
|     TString16 submod = curr_row.get(2);
 | ||
|     if (*curr_row.get(1)>' ')
 | ||
|     {
 | ||
|       if (patched_submodules.find(submod)<0)
 | ||
|         patched_submodules.add(submod);
 | ||
|     } else {
 | ||
|       if (submodules.find(submod)<0)
 | ||
|         submodules.add(submod);
 | ||
|     }
 | ||
|   } 
 | ||
| 
 | ||
|   // cerca i moduli che includono i sottomoduli patchati
 | ||
|   bool need_update(FALSE);
 | ||
|   TString16 sub_mod, sub_ver;
 | ||
|   int sub_patch;
 | ||
|   TSheet_field& modsheet = get_sheet()->mask().sfield(F_SHEET);
 | ||
|   FOR_EACH_SHEET_ROW(modsheet, midx, mriga)
 | ||
|   {
 | ||
|     TToken_string& curr_row=modsheet.row(midx);
 | ||
|     TString16 mod_code(curr_row.get(modsheet.cid2index(S_MODULE)));
 | ||
|     if (module_dependent(midx,patched_submodules, sub_mod, sub_ver, sub_patch))
 | ||
|     {
 | ||
|       if (version == sub_ver)
 | ||
|       {
 | ||
|         if ( patchlev > sub_patch 
 | ||
|           && yesno_box(FR("Il modulo '%s' dipende dal sottomodulo '%s'.\n Aggiorno il suo numero di patch a %d ?"),(const char *)mod_code,(const char *)sub_mod,patchlev))
 | ||
|         {
 | ||
|           curr_row.add(patchlev , modsheet.cid2index(S_PATCHLEVEL));
 | ||
|           curr_row.add(get(S_DATE) , modsheet.cid2index(S_DATE));
 | ||
|           need_update=TRUE;
 | ||
|         }
 | ||
|       } else 
 | ||
|         if (!sub_ver.blank())
 | ||
|           warning_box(FR("Il modulo '%s', dipendente dal sottomodulo '%s' \nha codice di release %s"),
 | ||
|             (const char *)mod_code, (const char *)sub_mod,(const char *)sub_ver);
 | ||
|     } 
 | ||
|     else if (module_dependent(midx,submodules, sub_mod, sub_ver, sub_patch))
 | ||
|     {
 | ||
|       if (version == sub_ver)
 | ||
|       {
 | ||
|         if ( patchlev > sub_patch 
 | ||
|           && noyes_box(FR("Il modulo '%s' dipende da sottomoduli del modulo '%s'.\n Aggiorno il suo numero di patch a %d ?"),(const char *)mod_code,(const char *)module,patchlev))
 | ||
|         {
 | ||
|           curr_row.add(patchlev , modsheet.cid2index(S_PATCHLEVEL));
 | ||
|           curr_row.add(get(S_DATE) , modsheet.cid2index(S_DATE));
 | ||
|           need_update=TRUE;
 | ||
|         }
 | ||
|       } else 
 | ||
|         if (!sub_ver.blank())
 | ||
|           warning_box(FR("Il modulo '%s', dipendente da sottomoduli del modulo '%s'\nha codice di release %s"),
 | ||
|             (const char *)mod_code, (const char *)sub_mod,(const char *)sub_ver);
 | ||
|     }
 | ||
|   }
 | ||
|   if (need_update)
 | ||
|     modsheet.force_update();
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TFascicolator_mask::patchl_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_TAB && f.focusdirty())
 | ||
|   {                       
 | ||
| //    TModule_mask& m = (TModule_mask&)f.mask();
 | ||
| //    m.dirty_composition();
 | ||
|   }  
 | ||
|   return TRUE;
 | ||
| }  
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| bool TCreadischi_mask::list_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {                
 | ||
|     TModule_mask& m = (TModule_mask&)f.mask();
 | ||
|     const TString& module = m.get(S_MODULE);
 | ||
| 
 | ||
|     if (module.not_empty())
 | ||
|     {
 | ||
|       TMod_composition_msk mm; 
 | ||
|       mm.load(module);
 | ||
|       if (mm.run() == K_ENTER)
 | ||
|         mm.save();
 | ||
|     }
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TFascicolator_mask::list_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {                
 | ||
|     TModule_mask& m = (TModule_mask&)f.mask();
 | ||
|     const TString& module = m.get(S_MODULE);
 | ||
| 
 | ||
|     if (module.not_empty())
 | ||
|     {
 | ||
|       TMod_composition_msk mm(TRUE); 
 | ||
|       mm.load(module);
 | ||
|       if (mm.run() == K_ENTER)
 | ||
|       {
 | ||
|         // Salvo nel .ini
 | ||
|         mm.save();
 | ||
|         m.dirty_composition();
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::confirm_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TFascicolator_mask::confirm_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {                       
 | ||
|     TModule_mask& m = (TModule_mask& )f.mask();
 | ||
|     const TString& module = m.get(S_MODULE);
 | ||
|     const int patchlevel=m.get_int(S_PATCHLEVEL);
 | ||
|     const bool dirty_module= m.field(S_DATE).dirty() || 
 | ||
|       m.field(S_PREPROCESS).dirty() || 
 | ||
|       m.field(S_POSTPROCESS).dirty() || 
 | ||
|       m.field(S_EXTERN).dirty();
 | ||
|     const bool dirty_version= m.field(S_VERSION).dirty() || 
 | ||
|       m.field(S_PATCHLEVEL).dirty();
 | ||
|     if (dirty_version || dirty_module)
 | ||
|     {
 | ||
|       TIndwin infobar(60,TR("Salvataggio composizione modulo"),FALSE,FALSE);
 | ||
|       TInstall_ini ini;                
 | ||
|       ini.set_paragraph(module);
 | ||
|       ini.set("Versione", m.get(S_VERSION));
 | ||
|       ini.set("Patch", patchlevel);
 | ||
|       ini.set("Data", m.get(S_DATE));
 | ||
|       ini.set("Moduli", m.get(S_EXTERN));
 | ||
|       ini.set("PreProcess", m.get(S_PREPROCESS));
 | ||
|       ini.set("PostProcess", m.get(S_POSTPROCESS));
 | ||
|       // sottomoduli
 | ||
|       if (dirty_version)
 | ||
|       {
 | ||
|         TString16 submodule=module;
 | ||
|         submodule<<'0';
 | ||
|         for (int i=0; i <=9; i++)
 | ||
|         {
 | ||
|           submodule[2]='0'+i;
 | ||
|           if (ini.set_paragraph(submodule))
 | ||
|           {
 | ||
|             ini.set("Versione", m.get(S_VERSION));
 | ||
|             ini.set("Patch", m.get(S_PATCHLEVEL));
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|     if (patchlevel>0 && (m.list_is_dirty() || dirty_version))
 | ||
|     {
 | ||
|       // controlla le consistenze tra patch di moduli diversi intrinsecamente correlati
 | ||
|       TIndwin infobar(60,TR("Controllo dipendenze tra sottomoduli"),FALSE,FALSE);
 | ||
|       TMod_composition_msk mc; 
 | ||
|       mc.load(module);
 | ||
|       m.check_patchlevels(mc);
 | ||
|     }
 | ||
|   }  
 | ||
|   return TRUE;
 | ||
| }  
 | ||
| 
 | ||
| bool TFascicolator_mask::creazip_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {                       
 | ||
|     TMask& m = f.mask();
 | ||
|     TMask_field& fconfirm= m.field(DLG_OK);
 | ||
|     confirm_handler(fconfirm, K_SPACE);
 | ||
|     TCreadischi_mask::creazip_handler(f,k);
 | ||
|   }  
 | ||
|   return TRUE;
 | ||
| }  
 | ||
| 
 | ||
| bool TCreadischi_mask::creazip_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {                       
 | ||
|     TMask& m = f.mask();
 | ||
|     const TString& module = m.get(S_MODULE);
 | ||
|     const bool agg = f.dlg() == S_CREATEPATCH;
 | ||
|     TCreadischi_mask& fm = (TCreadischi_mask&)m.get_sheet()->mask();
 | ||
| 
 | ||
|     if (fm.zip_module(module, agg, m.get_int(S_PATCHLEVEL)))
 | ||
|     {
 | ||
|       // creazione XXfconv.ini (esporta le info di conversione )
 | ||
|       TFilename fconv_path;
 | ||
|       fconv_path = fm.get(F_DISKPATH);
 | ||
|       fconv_path.add(module); 
 | ||
|       fconv_path << "fconv.ini";
 | ||
| 
 | ||
|       TFconv_ini fconv;
 | ||
|       fconv.export_module(module, fconv_path);
 | ||
|     }  
 | ||
|   }  
 | ||
|   return true;
 | ||
| }  
 | ||
| 
 | ||
| bool TCreadischi_mask::why_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k != K_SPACE)
 | ||
|     return TRUE;
 | ||
| 
 | ||
|   TArray_sheet& main_sheet = (TArray_sheet&)f.mask();
 | ||
|   const TFilename stopfile = main_sheet.row(main_sheet.selected()).get(1);
 | ||
|   TString16 module = stopfile.name(); module.cut(2);
 | ||
| 
 | ||
|   TFilename path = app().mask().get(F_DISKPATH);
 | ||
|   path.add(module); path << "????a.ini";
 | ||
|   
 | ||
|   TString_array inifiles;
 | ||
|   list_files(path, inifiles);
 | ||
|   inifiles.sort();
 | ||
|   TProgind pi(inifiles.items(), TR("Scansione archivi successivi..."), FALSE, TRUE);
 | ||
|   
 | ||
|   TString caption; caption << TR("File eliminabili da ") << stopfile.name();
 | ||
|   TArray_sheet sheet(3, 3, -3, -3, caption, HR("Modulo|File@20|Ultima Patch@50"));
 | ||
| 
 | ||
|   TAssoc_array files;
 | ||
|   TString_array para;
 | ||
|   TToken_string tok;
 | ||
|   FOR_EACH_ARRAY_ROW_BACK(inifiles, numf, filename)
 | ||
|   { 
 | ||
|     pi.addstatus(1);
 | ||
|     const bool is_last = stopfile == *filename;
 | ||
|     
 | ||
|     TConfig ini(*filename);
 | ||
|     ini.list_paragraphs(para);
 | ||
|     FOR_EACH_ARRAY_ROW_BACK(para, nump, paraname) if (paraname->len() == 3)
 | ||
|     {          
 | ||
|       ini.set_paragraph(*paraname);
 | ||
|       TAssoc_array& vars = ini.list_variables();  
 | ||
|       FOR_EACH_ASSOC_STRING(vars, obj, key, str)
 | ||
|       {             
 | ||
|         if (strncmp(key, "File(", 5) == 0)
 | ||
|         {
 | ||
|           tok = str;
 | ||
|           const int pipe = tok.find('|'); 
 | ||
|           if (pipe > 0) tok.cut(pipe);  
 | ||
|           tok.lower();
 | ||
|           
 | ||
|           if (is_last)
 | ||
|           {
 | ||
|             const TString* nextpatch = (const TString*)files.objptr(tok);
 | ||
|             TToken_string row;
 | ||
|             row = *paraname;
 | ||
|             row.add(tok);
 | ||
|             if (nextpatch)
 | ||
|               row.add(*nextpatch);
 | ||
|             else  
 | ||
|               row.add(TR("*** Nessuna ***"));  // Should never happen!
 | ||
|             sheet.add(row);
 | ||
|           }
 | ||
|           else
 | ||
|           {
 | ||
|             if (!files.is_key(tok))
 | ||
|               files.add(tok, *filename);
 | ||
|           }    
 | ||
|         }  
 | ||
|       }
 | ||
|     }
 | ||
|     if (is_last) break;
 | ||
|   }
 | ||
|   sheet.run();
 | ||
|   return FALSE;
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::testpatch_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k != K_SPACE)
 | ||
|     return true;
 | ||
|   
 | ||
|   TMask& m = f.mask();
 | ||
|   const TString& module = m.get(S_MODULE);
 | ||
|   TFilename path = app().mask().get(F_DISKPATH);
 | ||
|   path.add(module); path << "????a.ini";
 | ||
|   
 | ||
|   TArray_sheet sheet(3, 3, -3, -3, TR("File eliminabili"), HR("@1|Percorso assoluto@70"));
 | ||
|   sheet.add_button(DLG_USER+1, "Dettagli", 'D');
 | ||
|   sheet.set_handler(DLG_USER+1, why_handler);
 | ||
|   
 | ||
|   TString_array& inifiles = sheet.rows_array();
 | ||
|   list_files(path, inifiles);
 | ||
|   inifiles.sort();
 | ||
|   
 | ||
|   if (inifiles.items() > 0)
 | ||
|   {
 | ||
|     TProgind pi(inifiles.items(), TR("Scansione archivi..."), true, true);
 | ||
|     TAssoc_array files;
 | ||
|     TString_array para;
 | ||
|     TToken_string tok;
 | ||
|     FOR_EACH_ARRAY_ROW_BACK(inifiles, numf, filename)
 | ||
|     { 
 | ||
|       if (!pi.addstatus(1))
 | ||
|         break;
 | ||
| 
 | ||
|       bool can_be_deleted = true;
 | ||
|       TConfig ini(*filename, module);
 | ||
|       ini.list_paragraphs(para);
 | ||
|       FOR_EACH_ARRAY_ROW_BACK(para, nump, paraname) if (paraname->len() == 3)
 | ||
|       {          
 | ||
|         ini.set_paragraph(*paraname);
 | ||
|         TAssoc_array& vars = ini.list_variables();  
 | ||
|         FOR_EACH_ASSOC_STRING(vars, obj, key, str)
 | ||
|         {             
 | ||
|           if (strncmp(key, "File(", 5) == 0)
 | ||
|           {
 | ||
|             tok = str;
 | ||
|             const int pipe = tok.find('|'); 
 | ||
|             if (pipe > 0) tok.cut(pipe);  
 | ||
|             tok.lower();
 | ||
|             if (!files.is_key(tok))
 | ||
|             {
 | ||
|               files.add(tok);
 | ||
|               can_be_deleted = false;
 | ||
|             }
 | ||
|           }  
 | ||
|         }
 | ||
|       }
 | ||
|       if (can_be_deleted)
 | ||
|         filename->insert(" |", 0);
 | ||
|       else
 | ||
|         inifiles.destroy(numf, true);
 | ||
|     }
 | ||
|   }
 | ||
|   
 | ||
|   if (inifiles.items() == 0)
 | ||
|     return message_box(TR("Non e' stato rilevato nessun file eliminabile"));
 | ||
| 
 | ||
|   if (sheet.run() == K_ENTER) 
 | ||
|   {
 | ||
|     const long tot = sheet.checked();
 | ||
|     if (tot > 0 && yesno_box(FR("Confermare la cancellazione di %ld patches"), tot)) 
 | ||
|     {                      
 | ||
|       TWait_cursor hourglass;
 | ||
|       for (long i = sheet.items()-1; i >= 0; i--) if (sheet.checked(i))
 | ||
|       {
 | ||
|         const TFilename ininame = sheet.row(i).get(1);
 | ||
|         if (::remove(ininame) == 0)
 | ||
|         {
 | ||
|           TFilename name;
 | ||
|           for (int d = 1; d <= 9; d++)
 | ||
|           {
 | ||
|             name = ininame;
 | ||
|             name.ext(""); name << d << ".zip";
 | ||
|             if (::remove(name) != 0)
 | ||
|             { 
 | ||
|               if (d == 1)
 | ||
|                 error_box(FR("Errore di cancellazione del file %s"), (const char*)name);
 | ||
|               break;
 | ||
|             }
 | ||
|           }
 | ||
|         }  
 | ||
|         else
 | ||
|         {
 | ||
|           error_box(FR("Errore di cancellazione del file %s"), (const char*)ininame);
 | ||
|           break;
 | ||
|         }
 | ||
|       }  
 | ||
|     }
 | ||
|   }
 | ||
|   
 | ||
|   return true;  
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::import_export_handler(TMask_field& f, KEY k)
 | ||
| {
 | ||
|   if (k == K_SPACE)
 | ||
|   {                 
 | ||
|     const bool is_export = f.dlg() == S_EXPORT;
 | ||
|     const TMask& m = f.mask();
 | ||
|     const TString& module = m.get(S_MODULE);
 | ||
|                               
 | ||
|     const TCreadischi_mask& fm = (const TCreadischi_mask&)m.get_sheet()->mask();                          
 | ||
|     TFilename path = module;
 | ||
|     fm.build_export_path(path);
 | ||
| 
 | ||
|     path.add(module); path << "inst.ini"; path.lower();
 | ||
|     FILE_SPEC fs; xvt_fsys_convert_str_to_fspec(path, &fs);
 | ||
| 
 | ||
|     bool ok;
 | ||
|     
 | ||
|     DIRECTORY dir; 
 | ||
|     xvt_fsys_get_dir(&dir); // Salva directory corrente (Non usare la bacata xvt_fsys_save_dir)
 | ||
|     if (is_export)
 | ||
|       ok = xvt_dm_post_file_save(&fs, TR("Esporta il modulo in:")) == FL_OK;
 | ||
|     else
 | ||
|       ok = xvt_dm_post_file_open(&fs, TR("Importa il modulo da:")) == FL_OK;
 | ||
|     xvt_fsys_set_dir(&dir); // Ripristina directory corrente
 | ||
|     
 | ||
|     if (ok)
 | ||
|     {
 | ||
|       path = fs.dir.path;
 | ||
|       path.add(fs.name);
 | ||
|       if (is_export)
 | ||
|       {
 | ||
|         TInstall_ini inst;
 | ||
|         inst.export_module_paragraphs(module, path, TRUE);
 | ||
|       }  
 | ||
|       else
 | ||
|       { 
 | ||
|         TInstall_ini ini(path);
 | ||
|         ini.export_module_paragraphs(module, ini.default_name(), TRUE);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| const TFilename& TCreadischi_mask::build_export_path(TFilename& path) const
 | ||
| {    
 | ||
|   CHECK(path.not_empty(), "Please, specify the module");
 | ||
|   const TString module(path);
 | ||
|   
 | ||
|   path.cut(0);
 | ||
|   path << SLASH << "src" << SLASH << module;
 | ||
|   if (!path.exist()) 
 | ||
|   {
 | ||
|     path.cut(0);
 | ||
|     path << SLASH << 'u' << SLASH << user() << SLASH << "src" << SLASH << module;
 | ||
|     if (!path.exist()) 
 | ||
|     {
 | ||
|       path.cut(0);  
 | ||
|       path << SLASH << 'u' << SLASH << user() << SLASH << "p.due" << SLASH << module;
 | ||
|       if (!path.exist())     
 | ||
|         path.tempdir();
 | ||
|     }  
 | ||
|   }    
 | ||
|   path.lower();  
 | ||
|   return path;
 | ||
| }
 | ||
| 
 | ||
| void TCreadischi_mask::load()
 | ||
| { 
 | ||
|   TWait_cursor hourglass;
 | ||
|   TSheet_field& s = sfield(F_SHEET);
 | ||
|   
 | ||
|   TString tmp;
 | ||
|   TString_array modules;
 | ||
| 
 | ||
|   TInstall_ini ini;
 | ||
|   ini.list_paragraphs(modules);
 | ||
|   
 | ||
|   set(F_DISKSIZE, ini.get("DiskSize"));
 | ||
|   set(F_DISKPATH, ini.get("DiskPath"));
 | ||
|   
 | ||
|   FOR_EACH_ARRAY_ROW(modules, m, riga)
 | ||
|   {
 | ||
|     const TString& module = *riga;
 | ||
|     ini.set_paragraph(module);
 | ||
|     tmp = ini.get("Versione");
 | ||
|     if (module[0] == '_' ||  // linea di descrizione area
 | ||
|       (module.len() == 2 &&  // linea di modulo principale
 | ||
|         (!tmp.blank()  || show_all_modules())))
 | ||
|     {
 | ||
|       TToken_string& row = s.row(-1);
 | ||
|       row = ini.get("Descrizione");
 | ||
|       
 | ||
|       if (module[0] == '_')
 | ||
|       {
 | ||
|         s.disable_cell(s.items()-1, -1);
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         row.add(module);
 | ||
|       
 | ||
|         tmp = ini.get("Versione");
 | ||
|         row.add(tmp); // versione
 | ||
|             
 | ||
|         tmp = ini.get("Patch");
 | ||
|         row.add(tmp);
 | ||
|   
 | ||
|         tmp = ini.get("Data");
 | ||
|         row.add(tmp);
 | ||
|     
 | ||
|         tmp = ini.get("Moduli");
 | ||
|         row.add(tmp);
 | ||
|           
 | ||
|         tmp = ini.get("PreProcess");
 | ||
|         row.add(tmp);
 | ||
|       
 | ||
|         tmp = ini.get("PostProcess");
 | ||
|         row.add(tmp);
 | ||
|       } 
 | ||
|     } 
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TCreadischi_mask::save()
 | ||
| {
 | ||
|   TInstall_ini ini;
 | ||
|   ini.set("DiskSize", get(F_DISKSIZE));
 | ||
|   ini.set("DiskPath", get(F_DISKPATH));
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TFascicolator_mask::save()
 | ||
| {
 | ||
|   TSheet_field& s = sfield(F_SHEET);
 | ||
|   TCreadischi_mask::save();
 | ||
| 
 | ||
|   TProgind pi(s.items(), TR("Salvataggio in corso..."), FALSE, TRUE);
 | ||
|   TInstall_ini ini;
 | ||
|   
 | ||
|   TString tmp;
 | ||
|   FOR_EACH_SHEET_ROW_BACK(s, r, row)
 | ||
|   {          
 | ||
|     pi.addstatus(1);
 | ||
|   
 | ||
|     tmp = row->get(1);
 | ||
|     if (tmp.not_empty() && tmp != "xx")
 | ||
|     {
 | ||
|       ini.set_paragraph(tmp);
 | ||
|       
 | ||
|       tmp = row->get(0);
 | ||
|       ini.set("Descrizione", tmp);
 | ||
|       
 | ||
|       tmp = row->get(2);
 | ||
|       ini.set("Versione", tmp);
 | ||
| 
 | ||
|       tmp = row->get();
 | ||
|       ini.set("Patch", tmp);
 | ||
| 
 | ||
|       tmp = row->get();
 | ||
|       ini.set("Data", tmp);
 | ||
|       
 | ||
|       tmp = row->get();
 | ||
|       ini.set("Moduli", tmp);
 | ||
| 
 | ||
|       tmp = row->get();
 | ||
|       ini.set("PreProcess", tmp);
 | ||
| 
 | ||
|       tmp = row->get();
 | ||
|       ini.set("PostProcess", tmp);
 | ||
|     }  
 | ||
|   }  
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::zip_file(const char* archive, const char* listfile) const
 | ||
| {  
 | ||
|   TString msg;
 | ||
|   msg.format(TR("Creazione del file compresso %s..."), (const char*)archive);
 | ||
| 
 | ||
|   TIndwin waitw(100,msg,FALSE,FALSE); 
 | ||
|   TWait_cursor hourglass;
 | ||
| 
 | ||
| 	return aga_zip_filelist(listfile, archive);
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::move_file(const TFilename& file, const char* dir) const
 | ||
| {
 | ||
|   TFilename dest(dir);
 | ||
|   dest.add(file.name());
 | ||
|   
 | ||
|   const long filesize = fsize(file);
 | ||
|   
 | ||
|   bool space_ok = xvt_fsys_is_network_drive(dest) != 0; // Pezza per far funzionare //192.168.4.3/...
 | ||
|   while (!space_ok)
 | ||
|   {
 | ||
|     space_ok = xvt_fsys_test_disk_free_space(dest, filesize) != 0;
 | ||
|     if (!space_ok)
 | ||
|     {
 | ||
|       TString msg(128);
 | ||
|       msg << TR("Lo spazio sull'unita' e' insufficiente");
 | ||
|       if (xvt_fsys_is_removable_drive(dest))
 | ||
|       {
 | ||
|         msg << TR(":\nInserire un nuovo disco e ritentare?");
 | ||
|         if (!yesno_box(msg))
 | ||
|           return FALSE;
 | ||
|       }
 | ||
|       else
 | ||
|         return error_box(msg);  
 | ||
|     }  
 | ||
|   }  
 | ||
| 
 | ||
|   bool write_ok = TRUE;
 | ||
|   bool user_abort = FALSE;
 | ||
|   do
 | ||
|   {
 | ||
|     write_ok = ::fcopy(file, dest);
 | ||
|     if (write_ok) 
 | ||
|       ::remove(file);  
 | ||
|     else
 | ||
|     {
 | ||
|       if (!yesno_box(FR("Errore di copia del file %s.\nSi desidera riprovare?"),
 | ||
|                      (const char*)file))
 | ||
|         user_abort = TRUE;
 | ||
|     }    
 | ||
|   } while (!write_ok && !user_abort);
 | ||
|     
 | ||
|   return write_ok;
 | ||
| }
 | ||
| 
 | ||
| // Dato il file Pippo.zip lo splitta in Pippo1.zip, Pippo2.zip, Pippo?.zip
 | ||
| int TCreadischi_mask::split_file(const TFilename& archive, size_t chunk_size) const
 | ||
| {
 | ||
|   int disks = 1;
 | ||
| 	const size_t tot_size = ::fsize(archive);
 | ||
|   if (chunk_size > 0 && chunk_size < tot_size)
 | ||
|   {
 | ||
|     TFilename sommario(archive); 
 | ||
|     sommario.ext("ini");
 | ||
|     chunk_size -= ::fsize(sommario); 
 | ||
|     const long minsize = 720*1024L;
 | ||
|     if (chunk_size < minsize)
 | ||
|       chunk_size = minsize;
 | ||
| 
 | ||
| 		FILE* inf = fopen(archive, "rb");
 | ||
| 		if (inf == NULL)
 | ||
| 			return 0;
 | ||
| 
 | ||
| 	  TString msg; msg << TR("Separazione del file ") << archive << "...";
 | ||
|     TProgind pi(tot_size, msg, FALSE, TRUE); 
 | ||
| 		
 | ||
| 		byte* buff = new byte[chunk_size];
 | ||
| 		for (int d = 1; ; d++)
 | ||
| 		{
 | ||
| 			const size_t r = fread(buff, 1, chunk_size, inf);
 | ||
| 			pi.addstatus(r);
 | ||
| 			if (r > 0)
 | ||
| 			{
 | ||
|         TFilename chunk(archive);
 | ||
| 	  		chunk.ext(""); chunk << d; chunk.ext("zip");
 | ||
|   			FILE* ouf = fopen(chunk, "wb");
 | ||
| 			  fwrite(buff, r, 1, ouf);
 | ||
| 				fclose(ouf);
 | ||
| 				disks = d;
 | ||
| 			}
 | ||
| 			else
 | ||
| 				break;
 | ||
| 		}
 | ||
| 		delete buff;
 | ||
| 		fclose(inf);
 | ||
|   
 | ||
|     ::remove(archive);
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     TFilename archive1(archive);
 | ||
|     archive1.ext("");
 | ||
|     archive1 << '1';
 | ||
|     archive1.ext("zip");
 | ||
|     ::rename(archive,archive1);
 | ||
|   }
 | ||
|   
 | ||
|   return disks;  
 | ||
| }
 | ||
| 
 | ||
| long TFascicolator_mask::find_signature(const TFilename& filename, const char* signature) const
 | ||
| {       
 | ||
|   bool found = FALSE;
 | ||
|   long position = -1;
 | ||
|   int compare = 0;
 | ||
|   ifstream infile(filename, ios::in | ios::binary);
 | ||
|   for (int car = infile.get(); car != EOF; car = infile.get())
 | ||
|   {                              
 | ||
|     if (car == signature[compare])
 | ||
|     {            
 | ||
|       if (compare == 0)
 | ||
|         position = infile.tellg()-1L;
 | ||
|       compare++;
 | ||
|       if (signature[compare] == '\0')
 | ||
|       {
 | ||
|         found = TRUE;
 | ||
|         break;
 | ||
|       }  
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       if (compare > 0)
 | ||
|         infile.seekg(position+1, ios::beg);
 | ||
|       compare = 0;
 | ||
|     }
 | ||
|   }  
 | ||
|   return found ? position : -1;
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::set_version_info(const TFilename& filename, 
 | ||
|                                           TInstall_ini& ini, const char* module) const
 | ||
| {           
 | ||
|   return TRUE;
 | ||
| }
 | ||
| 
 | ||
| bool TFascicolator_mask::set_version_info(const TFilename& filename, 
 | ||
|                                           TInstall_ini& ini, const char* module) const
 | ||
| {           
 | ||
|   bool ok = FALSE;
 | ||
|   TString80 str = "Don't cry for me "; str << "Argentina.";
 | ||
|   long position = find_signature(filename, str);
 | ||
|   if (position > 0)
 | ||
|   {
 | ||
|     fstream outfile(filename, ios::in | ios::out | ios::binary);
 | ||
|     position += str.len();
 | ||
|     outfile.seekp(position);
 | ||
|     if (outfile.good())
 | ||
|     {                    
 | ||
|       int year, release, tag, patch, checksum;
 | ||
|       ini.version_info(module, year, release, tag, patch);
 | ||
|       checksum = year + release + tag + patch;
 | ||
|       str.format("%04d.%02d.%02d.%04d.%04d", year, release, tag, patch, checksum);
 | ||
| 
 | ||
|       TString oldfirm("XXXX.XX.XX.XXXX.XXXX");
 | ||
|       outfile.read(oldfirm.get_buffer(),20);
 | ||
|       if (oldfirm!=str)
 | ||
|       {
 | ||
|         outfile.seekp(position);
 | ||
|         outfile.write(str, str.len());  
 | ||
|       }
 | ||
|       ok = outfile.good() != 0;      
 | ||
|       if (!ok)
 | ||
|         error_box("Error writing signature in %s error n. %d", (const char *) filename, errno);
 | ||
|     }  
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TCreadischi_mask::zip_module(const TString& main_module, bool agg, int patch_level) const
 | ||
| {  
 | ||
|   TString_array arr;
 | ||
|   TInstall_ini ini;
 | ||
| 
 | ||
|   TFilename sommario;     //e' il file .ini con l'elenco dei files (XX@@@@a.ini) 
 | ||
|   TFilename sommario_txt; //e' il file .txt con l'elenco dei files (XX@@@@.txt) 
 | ||
| 
 | ||
|   sommario.tempdir();
 | ||
|   sommario.add(main_module);
 | ||
| 
 | ||
|   if (agg)
 | ||
|   {
 | ||
|     if (patch_level <= 0)
 | ||
|       return error_box(TR("Il numero di patch deve essere superiore a zero"));
 | ||
| 
 | ||
|     //crea i nomi del file .ini e del .txt con l'elenco dei files (il .txt NON ci vuole in caso di pacco di..
 | ||
|     //..installazione completo tipo XXinst.ini)
 | ||
|     //File .ini
 | ||
|     TString16 name, name_txt; 
 | ||
|     name.format("%04da.ini", patch_level);    //.ini
 | ||
|     sommario << name;                  // Nome del file sommario aggiornamento
 | ||
|   }  
 | ||
|   else
 | ||
|     sommario << "inst.ini";            // Nome del file sommario completo
 | ||
|   
 | ||
|   //riempie arr, TString_array con i files da caricare (sono quelli elencati nel .ini e contenuti nel .zip)
 | ||
|   ini.build_complete_list(main_module, arr, sommario, agg);
 | ||
| 
 | ||
|   //se non ci sono files lascia perdere
 | ||
|   if (arr.items() == 0)
 | ||
|   {
 | ||
|     ::remove(sommario);
 | ||
|     return error_box(TR("Nessun file da compattare"));
 | ||
|   }
 | ||
| 
 | ||
|   //e' il momento di compilare il .txt con l'elenco files per il prode testatore
 | ||
|   if (agg && !arr.empty())
 | ||
|   {
 | ||
|     //File .txt
 | ||
|     sommario_txt.format("%s%s%04d.txt", 
 | ||
|                         (const char*)sommario.path(), (const char*)main_module, patch_level);
 | ||
|     ofstream txt(sommario_txt);
 | ||
|     FOR_EACH_ARRAY_ROW(arr, r, row)
 | ||
|       txt << row->get(0) << endl;
 | ||
|   }
 | ||
| 
 | ||
|   const TFilename path = get(F_DISKPATH);
 | ||
|   // *****************
 | ||
|   // creazione ZIP
 | ||
|   TFilename archivio(sommario);
 | ||
|   archivio.ext("zip");            // Nome del file archivio completo
 | ||
|   
 | ||
|   bool aborted = false;                                                              
 | ||
|   // ******************
 | ||
|   // compilazione lista e relativa firma dei files
 | ||
|   TString msg;
 | ||
|   if (path.blank())
 | ||
|     msg << TR("Controllo dei file per ") <<  archivio << " ...";
 | ||
|   else
 | ||
|     msg << TR("Preparazione dei file per ") <<  archivio << " ...";
 | ||
| 
 | ||
|   TFilename filelist;
 | ||
|   filelist.temp("", main_module);
 | ||
|   struct _stat info;
 | ||
|   time_t lasttime = 0;
 | ||
|   
 | ||
|   // blocco della prima Progind
 | ||
|   { 
 | ||
|     ofstream fileh(filelist);
 | ||
|     TProgind pi(arr.items(), msg, true, true); 
 | ||
|     TFilename cmd;
 | ||
|     
 | ||
|     FOR_EACH_ARRAY_ROW_BACK(arr, i, row)
 | ||
|     {                    
 | ||
|       pi.addstatus(1);
 | ||
|       if (pi.iscancelled())
 | ||
|       {
 | ||
|         aborted = true;
 | ||
|         break;
 | ||
|       }
 | ||
|       cmd = row->get(0);
 | ||
|       if (cmd.exist())
 | ||
|       {                   
 | ||
|         // Aggiungo il nome corrente alla lista dei files da compattare
 | ||
|         fileh << cmd << '\n';      
 | ||
|         if (xvt_str_compare_ignoring_case(cmd.ext(), "exe") == 0)
 | ||
|         {
 | ||
|           TString4 submod;
 | ||
|           submod.strncpy(row->get(2), 2);
 | ||
|           set_version_info(cmd, ini, submod);  
 | ||
|         }  
 | ||
|         _stat((const char *)cmd,&info);
 | ||
|         lasttime = max(lasttime, info.st_mtime);
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         // Se non trovo anche uno solo dei files nella lista, <20> un casino
 | ||
|         TString msg(128);
 | ||
|         msg << TR("Impossibile aprire il file ") << cmd << TR(". Interrompere?");
 | ||
|         if (yesno_box(msg))
 | ||
|         {
 | ||
|           aborted = true;
 | ||
|           break;
 | ||
|         } 
 | ||
|       } 
 | ||
|     }
 | ||
|     fileh.close();
 | ||
|   }
 | ||
| 
 | ||
|   // Se non specifico un path ho gia' finito
 | ||
|   if (path.blank())
 | ||
|   {
 | ||
|     message_box(TR("Nessun percorso specificato. Il pacchetto non verra' creato"));
 | ||
|     return false;
 | ||
|   }
 | ||
| 
 | ||
|   TFilename zipfile = path;
 | ||
|   zipfile.add(archivio.name());
 | ||
|   zipfile.ext("");
 | ||
|   zipfile << '1';
 | ||
|   zipfile.ext("zip");
 | ||
|   if (zipfile.exist())
 | ||
|   {
 | ||
|     _stat((const char *)zipfile,&info);
 | ||
|     if (lasttime   <= info.st_mtime)
 | ||
|     {
 | ||
|       aborted = !yesno_box(FR("Il file %s risulta gi<67> aggiornato.\nSi desidera rigenerarlo comunque?"),(const char *)zipfile);
 | ||
|     }
 | ||
|     if (!aborted && !agg)
 | ||
|     {
 | ||
|       // main zip updated; are there some patches?
 | ||
|       TFilename patchfile = zipfile.path();
 | ||
|       TString16 modpatch;
 | ||
|       modpatch.format("%s%04da.ini",(const char *)main_module,patch_level);
 | ||
|       patchfile.add(modpatch);
 | ||
|       if (patchfile.exist())
 | ||
|       {
 | ||
|         _stat((const char *)patchfile,&info);
 | ||
|         if (lasttime   <= info.st_mtime)
 | ||
|           aborted = !yesno_box(FR("Il file di patch %s \nrisulta gi<67> aggiornato.\nSi desidera procedere comunque alla generazione di %s ?"),(const char *)patchfile,(const char *)zipfile);
 | ||
|       }
 | ||
|     } 
 | ||
|   } 
 | ||
|   if (aborted)
 | ||
|   {
 | ||
|     ::remove(sommario);       //elimina il .ini
 | ||
|     ::remove(sommario_txt);   //elimina il .txt
 | ||
|     ::remove(filelist);       //elimina il file lista-file
 | ||
|     return TRUE;
 | ||
|   }
 | ||
| 
 | ||
|   zip_file(archivio, filelist);    // Compatto gli eventuali ultimi rimasti
 | ||
|   ::remove(filelist); // elimina il file lista-file    
 | ||
|     
 | ||
|   const size_t size = get_long(F_DISKSIZE) * 1024;  
 | ||
|   const int disks = split_file(archivio, size);
 | ||
|     
 | ||
|   // Memorizza il numero dei dischetti nel sommario
 | ||
|   ini.set("Dischi", disks, main_module);     // Aggiorna install.ini
 | ||
|   ini.export_paragraph(main_module, sommario,TRUE); // Aggiorna sommario
 | ||
|     
 | ||
|   const char drive = toupper(path[0]);  
 | ||
|   const bool floppy = xvt_fsys_is_removable_drive(path) != 0;
 | ||
|     
 | ||
| 	msg.format(TR("Creazione del file %s"), (const char*)archivio);
 | ||
|   TProgind pi(disks, msg, FALSE, TRUE);
 | ||
|   for (int d = 1; d <= disks && !aborted; d++)
 | ||
|   {            
 | ||
|     if (floppy)
 | ||
|       message_box(TR("Inserire il disco %d di %d nell'unita`:"), d, disks);
 | ||
|   
 | ||
|     // Costruisco il nome del file da copiare su dischetto  
 | ||
|     TFilename src(archivio);
 | ||
|     src.ext("");
 | ||
|     src << d;
 | ||
|     src.ext("zip");
 | ||
|   
 | ||
|     msg.format(TR("Generazione del disco %d/%d del modulo %s..."), d, disks, (const char*)main_module);
 | ||
|     pi.set_text(msg);
 | ||
| 		pi.addstatus(1);
 | ||
|     do_events();
 | ||
|   
 | ||
|     bool ok = true;
 | ||
|     if (d == 1)
 | ||
|     {
 | ||
|       ok = move_file(sommario, path);
 | ||
|       if (sommario_txt.exist())
 | ||
|         move_file(sommario_txt, path);
 | ||
|     }
 | ||
|     if (ok)
 | ||
|       ok = move_file(src, path);
 | ||
|     aborted = !ok || pi.iscancelled();
 | ||
|   }
 | ||
|   // scrive il sommario completo 
 | ||
|   if (!agg && size==0)
 | ||
|   {
 | ||
|     archivio = path;
 | ||
|     archivio.add("install.ini");
 | ||
|     fcopy("install.ini",(const char *)archivio);
 | ||
|   }
 | ||
|     
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| TCreadischi_mask::TCreadischi_mask()
 | ||
|                   : TMask("ba1600a")
 | ||
| { 
 | ||
|   TSheet_field& s = sfield(F_SHEET);
 | ||
|   s.set_notify(modules_notify);
 | ||
|   
 | ||
|   TMask& m = s.sheet_mask();
 | ||
| 
 | ||
|   m.set_handler(DLG_OK, confirm_handler);
 | ||
|   m.set_handler(S_LIST, list_handler);
 | ||
|   m.set_handler(S_CREATEZIP, creazip_handler);
 | ||
|   m.set_handler(S_CREATEPATCH, creazip_handler);
 | ||
|   m.set_handler(S_TESTPATCH, testpatch_handler);
 | ||
|   m.hide(S_IMPORT);
 | ||
|   m.set_handler(S_EXPORT, import_export_handler);
 | ||
|   s.disable();
 | ||
| }
 | ||
| 
 | ||
| TFascicolator_mask::TFascicolator_mask()
 | ||
|                   : TCreadischi_mask()
 | ||
| { 
 | ||
|   TSheet_field& s = sfield(F_SHEET);
 | ||
|   s.set_notify(TCreadischi_mask::modules_notify);
 | ||
|   
 | ||
|   TMask& m = s.sheet_mask();
 | ||
| 
 | ||
|   m.set_handler(DLG_OK, confirm_handler);
 | ||
|   m.set_handler(S_LIST, list_handler);
 | ||
|   m.set_handler(S_CREATEZIP, creazip_handler);
 | ||
|   m.set_handler(S_CREATEPATCH, creazip_handler);
 | ||
|   m.set_handler(S_PATCHLEVEL, patchl_handler);
 | ||
|   m.show(S_IMPORT);
 | ||
|   m.set_handler(S_IMPORT, import_export_handler);
 | ||
|   s.enable(TRUE);
 | ||
|   s.enable_column(S_MODULE,TRUE);
 | ||
|   s.enable_column(S_VERSION,TRUE);
 | ||
|   s.enable_column(S_PATCHLEVEL,TRUE);
 | ||
|   s.enable_column(S_EXTERN,TRUE);
 | ||
|   s.enable_column(S_PREPROCESS,TRUE);
 | ||
|   s.enable_column(S_POSTPROCESS,TRUE);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Programma principale
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| void TFascicolator::main_loop()
 | ||
| {
 | ||
|   _mask = new TFascicolator_mask;
 | ||
|   _mask->load();
 | ||
|   int key;
 | ||
|   do 
 | ||
|   {
 | ||
|     key = _mask->run();
 | ||
|     if (key == K_ENTER)
 | ||
|       _mask->save();
 | ||
|   }
 | ||
|   while (key != K_ENTER && key != K_QUIT);
 | ||
|   delete _mask; _mask = NULL;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| void TCreazione_dischi::main_loop()
 | ||
| {
 | ||
|   TCreadischi_mask m;
 | ||
|   m.load();
 | ||
|   int key;
 | ||
|   do 
 | ||
|   {
 | ||
|     key=m.run();
 | ||
|     if (key == K_ENTER)
 | ||
|       m.save();
 | ||
|   }
 | ||
|   while (key != K_ENTER && key != K_QUIT);
 | ||
| }
 | ||
| 
 | ||
| // Cerca un file nell'array di colonne e ne restituisce il numero del sottomodulo
 | ||
| // -1 se 
 | ||
| int find(const TString& name, TString_array & rows) 
 | ||
| {
 | ||
|   int r;
 | ||
|   for(r = rows.items()-1; r >=0 ; r-- )
 | ||
|   {
 | ||
|     if (name.compare(rows.row(r).get(0), -1, TRUE) == 0)
 | ||
|       break;
 | ||
|   }
 | ||
|   return r;
 | ||
| }
 | ||
| 
 | ||
| int ba1600(int argc, char* argv[])
 | ||
| { 
 | ||
|   if (user() == ::dongle().administrator())
 | ||
|   {
 | ||
|     if (argc>2 && strcmp(argv[1],"GODMODE"))
 | ||
|     {
 | ||
|       TFascicolator app;
 | ||
|       app.run(argc, argv, "Megascicolator");
 | ||
|     } 
 | ||
|     else 
 | ||
|     {
 | ||
|       TCreazione_dischi app;
 | ||
|       app.run(argc, argv, TR("Creazione dischetti"));
 | ||
|     }
 | ||
|   } 
 | ||
| 	else 
 | ||
|     error_box(FR("L'utente %s non e' abilitato all'esecuzione di questo programma"), (const char*)user());
 | ||
|   return 0;
 | ||
| }
 |