#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 bool use_files() const { return TRUE; } 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); TAuto_token_string altri(get("Moduli", module)); FOR_EACH_TOKEN(altri, mod) { const TString16 submodule = mod; // Lista dei files apparteneti 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(); } 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'); char main_module[3]={0,0,0}; strncpy(main_module, 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); } 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) { TScanner scanner("prassi.aut"); int module_code; for (module_code = 0; scanner.line().not_empty(); module_code++) { if (scanner.token().compare(module, 2, TRUE) == 0) break; } scanner.close(); TConfig sommario(summary); TString_array paragraphs; list_paragraphs(paragraphs); paragraphs.sort(); 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); } } } } } /////////////////////////////////////////////////////////// // TAuto_token_string /////////////////////////////////////////////////////////// /* TAuto_token_string& TAuto_token_string::create(const char* ts) { // Copia la stringa set(ts); // Calcola il separatore for (const char* s = get_buffer(); *s; s++) { if (strchr("|;,!^&+\t\n", *s) != NULL) { separator(*s); break; } } return *this; } */ /////////////////////////////////////////////////////////// // 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); static bool file_handler(TMask_field& f, KEY k); static bool edit_handler(TMask_field& f, KEY k); static bool link_handler(TMask_field& f, KEY k); static bool deselect_handler(TMask_field& f, KEY k); static bool isam_handler(TMask_field& f, KEY k); bool kill_missing(const char* name, bool update); 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; } 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("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; } 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) { TFilename start; DIRECTORY dir; xvt_fsys_get_dir(&dir); xvt_fsys_convert_dir_to_str(&dir, start.get_buffer(), start.size()); FILE_SPEC fs; xvt_fsys_get_dir(&fs.dir); strcpy(fs.type, ""); strcpy(fs.name, "*.*"); strcpy(fs.creator, "SETUP"); FL_STATUS ok = xvt_dm_post_file_open(&fs, "Selezionare il file ..."); xvt_fsys_set_dir(&dir); if (ok == FL_OK) { TFilename file; xvt_fsys_convert_dir_to_str(&fs.dir, file.get_buffer(), file.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("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::edit_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TFilename file = f.mask().get(101); if (stricmp(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; } 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,"Selezione archivio", "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 = stricmp(r1->get(-2), r2->get(-2)); if (cmp == 0) cmp = stricmp(*r1, *r2); return cmp; } void TMod_composition_msk::load(const TString& module) { TWait_cursor hourglass; set(F_MODULE, module); TInstall_ini ini; TSheet_field& s = sfield(F_SHEET); ini.build_list(module, s.rows_array()); s.rows_array().TArray::sort(file_compare); TSheet_field& p = sfield(F_PROGRAMS); 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); 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); } } 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); 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); } else { s.disable(); // Read-only sheet //hide(DLG_OK); // hide(F_DESELECT); //hide(DLG_CANCEL); 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, long 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("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("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("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("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 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,"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,"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; TFconv_ini fconv; // fconv_path = fm.get(F_DISKPATH); fconv_path.add(module); fconv_path << "fconv.ini"; 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(), "Scansione archivi successivi...", FALSE, TRUE); TString caption; caption << "File eliminabili da " << stopfile.name(); TArray_sheet sheet(3, 3, -3, -3, caption, "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("*** 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, "File eliminabili", "@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(), "Scansione archivi...", FALSE, TRUE); TAssoc_array files; TString_array para; TToken_string tok; FOR_EACH_ARRAY_ROW_BACK(inifiles, numf, filename) { pi.addstatus(1); 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("Non e' stato rilevato nessun file eliminabile"); if (sheet.run() == K_ENTER) { const long tot = sheet.checked(); if (tot > 0 && yesno_box("Confermare la cancellazione di %ld file", tot)) { TWait_cursor hourglass; for (long i = sheet.items()-1; i >= 0; i--) if (sheet.checked(i)) { for (int d = 1; d <= 9; d++) { TFilename name = sheet.row(i).get(1); name.ext(""); name << d << ".zip"; if (::remove(name) != 0) { if (d == 1) error_box("Errore di cancellazione del file %s", (const char*)name); 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); FILE_SPEC fs; xvt_fsys_convert_str_to_dir(path.get_buffer(), &fs.dir); path.add(module); path << "inst.ini"; path.lower(); strcpy(fs.type, "ini"); strcpy(fs.name, path.name()); strcpy(fs.creator, "INST"); 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, "Esporta il modulo in:") == FL_OK; else ok = xvt_dm_post_file_open(&fs, "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); /*TFconv_ini fconv; path = path.path(); path.add(module); path << "fconv.ini"; fconv.export_module(module, path);*/ } else { TInstall_ini ini(path); ini.export_module_paragraphs(module, ini.default_name(),TRUE); /*path = path.path(); path.add(module); path << "fconv.ini"; TFconv_ini fconv(path); fconv.export_module(module, "fconv.ini");*/ } } } 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(), "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 << "Creazione del file temporaneo " << archive << "..."; TIndwin waitw(100,msg,FALSE,FALSE); TWait_cursor hourglass; TFilename cmd; int err=0; cmd << "zip.pif " << archive << ' ' << listfile; TExternal_app app(cmd); err = app.run(FALSE, FALSE, FALSE, FALSE); return err == 0; } 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 = FALSE; while (!space_ok) { space_ok = ::os_test_disk_free_space(dest, filesize); if (!space_ok) { TString msg(128); msg << "Lo spazio sull'unita' e' insufficiente"; if (::os_is_removable_drive(dest)) { msg << ":\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("Errore di copia del file %s.\nSi desidera riprovare?", (const char*)file)) user_abort = TRUE; } } while (!write_ok && !user_abort); return write_ok; } int TCreadischi_mask::split_file(const TFilename& archive, long size) const { TWait_cursor hourglass; int disks = 1; if (size > 0L) { TFilename sommario(archive); sommario.ext("ini"); size -= ::fsize(sommario); const long minsize = 360*1024L; if (size < minsize) size = minsize; DIRECTORY curdir, tmpdir; xvt_fsys_get_dir(&curdir); // Legge directory corrente // Costruisce percorso assoluto dello splitter TFilename cmd; xvt_fsys_convert_dir_to_str(&curdir, cmd.get_buffer(), cmd.size()); cmd.add("zipsplit.pif"); cmd << " -n " << size << " -b " << archive.path() << ' ' << archive; // Salta alla directory temporanea xvt_fsys_convert_str_to_dir((char*)archive.path(), &tmpdir); xvt_fsys_set_dir(&tmpdir); // Esegue lo splitter nella directory temporanea TExternal_app app(cmd); int err = app.run(FALSE, FALSE, FALSE, FALSE); // Torna nella directory principale xvt_fsys_set_dir(&curdir); if (err != NOERR) return error_box("Errore %d durante lo splitting del file %s", err, (const char*)archive); // Conta il numero di dischetti generati TFilename src; for (int d = 2; ; d++) { src = archive; src.ext(""); src << d; src.ext("zip"); if (::fexist(src)) disks = d; else break; } ::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::nocreate | ios::in | ios::binary); for (int car = infile.get(); car != EOF; car = infile.get()) { if (car == signature[compare]) { if (compare == 0) position = infile.tellg()-1; 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::nocreate | 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.%03d.%04d", year, release, tag, patch, checksum); TString oldfirm("XXXX.XX.XX.XXX.XXXX"); outfile.read(oldfirm.get_buffer(),19); 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; sommario.tempdir(); sommario.add(main_module); if (agg) { if (patch_level <= 0) return error_box("Il numero di patch deve essere superiore a zero"); TString16 name; name.format("%04da.ini", patch_level); sommario << name; // Nome del file sommario aggiornamento } else sommario << "inst.ini"; // Nome del file sommario completo ini.build_complete_list(main_module, arr, sommario, agg); if (arr.items() == 0) { ::remove(sommario); return error_box("Nessun file da compattare"); } 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 << "Controllo dei file per " << archivio << " ..."; else msg << "Preparazione dei file per " << archivio << " ..."; TFilename filelist; filelist.temp("", main_module); struct _stat info; unsigned long 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 (stricmp(cmd.ext(), "exe") == 0) { TString16 submod = row->get(2); submod.cut(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, è un casino TString msg(128); msg << "Impossibile aprire il file " << cmd << ". Interrompere?"; if (yesno_box(msg)) { aborted = TRUE; break; } } } fileh.close(); } // Se non specifico un path ho gia' finito if (path.blank()) { message_box("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("Il file %s risulta già 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("Il file di patch %s \nrisulta già aggiornato.\nSi desidera procedere comunque alla generazione di %s ?",(const char *)patchfile,(const char *)zipfile); } } } if (aborted) { ::remove(sommario); ::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 msg.cut(0); msg << "Separazione del file " << archivio << " ..."; TIndwin pi(60, msg, FALSE, FALSE); const long 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 = os_is_removable_drive(path); for (int d = 1; d <= disks && !aborted; d++) { if (floppy) message_box("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.cut(0); msg << "Generazione del disco " << d << " di " << disks << " del modulo " << main_module << " ..."; pi.set_text(msg); do_events(); bool ok = TRUE; if (d == 1) ok = move_file(sommario, 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) { for(int 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, "Creazione dischetti"); } } else error_box("L'utente %s non e' abilitato all'esecuzione di questo programma", (const char*)user()); return 0; }