From 63bbe4e1d25390413f8260375dca4a7c8bd20a96 Mon Sep 17 00:00:00 2001 From: guy Date: Thu, 30 Oct 1997 15:13:59 +0000 Subject: [PATCH] ba1.cpp Aggiunte chiamate ai "fascicolatori" ba1.h Dichiarazioni dei fascicolatori ba1.url Aggiunto menu dei fascicolatori ba1600.cpp Corretto e ampliato programma di fascicolazione ba1600.h Classi di utlita' comune ai due fascicolatori ba1600a.uml Aggiornato sheet fascicolatore ba1600b.uml Aggiornato sheet lista files ba1600a.h Aggiunti campi ba1700.cpp Programma di installazione ba1700a.* Maschera per programma di installazione git-svn-id: svn://10.65.10.50/trunk@5496 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ba/ba1.cpp | 2 + ba/ba1.h | 1 + ba/ba1.url | 22 +- ba/ba1600.cpp | 871 +++++++++++++++++++++++++++++++++++++++++-------- ba/ba1600.h | 42 ++- ba/ba1600a.h | 19 ++ ba/ba1600a.uml | 73 +++-- ba/ba1600b.uml | 29 +- ba/ba1700.cpp | 416 +++++++++++++++++++++++ ba/ba1700a.h | 11 + ba/ba1700a.uml | 104 ++++++ 11 files changed, 1400 insertions(+), 190 deletions(-) create mode 100755 ba/ba1600a.h create mode 100755 ba/ba1700.cpp create mode 100755 ba/ba1700a.h create mode 100755 ba/ba1700a.uml diff --git a/ba/ba1.cpp b/ba/ba1.cpp index e79890124..8264042dd 100755 --- a/ba/ba1.cpp +++ b/ba/ba1.cpp @@ -20,6 +20,8 @@ int main(int argc,char** argv) ba1500(argc,argv); break; case 5: ba1600(argc,argv); break; + case 6: + ba1700(argc,argv); break; default: ba1100(argc,argv); break; } diff --git a/ba/ba1.h b/ba/ba1.h index d78210f04..d50d7c95d 100755 --- a/ba/ba1.h +++ b/ba/ba1.h @@ -7,6 +7,7 @@ int ba1300(int argc, char** argv); int ba1400(int argc, char** argv); int ba1500(int argc, char** argv); int ba1600(int argc, char* argv[]); +int ba1700(int argc, char* argv[]); #endif // __BA1_H diff --git a/ba/ba1.url b/ba/ba1.url index e55906f79..57815ab16 100755 --- a/ba/ba1.url +++ b/ba/ba1.url @@ -2,38 +2,44 @@ /* ba1 -0 */ MENU TASK_MENUBAR - SUBMENU MENU_FILE "~File" + SUBMENU MENU_FILE "~File" /* ba1 -1 */ MENUBAR MENU_BAR(1) MENU MENU_BAR(1) - SUBMENU MENU_FILE "~File" - ITEM BAR_ITEM(1) "~Test" + SUBMENU MENU_FILE "~File" + ITEM BAR_ITEM(1) "~Test" /* ba1 -2 */ MENUBAR MENU_BAR(2) MENU MENU_BAR(2) - SUBMENU MENU_FILE "~File" + SUBMENU MENU_FILE "~File" /* ba1 -3 */ MENUBAR MENU_BAR(3) MENU MENU_BAR(3) - SUBMENU MENU_FILE "~File" + SUBMENU MENU_FILE "~File" /* ba1 -4 */ MENUBAR MENU_BAR(4) MENU MENU_BAR(4) - SUBMENU MENU_FILE "~File" + SUBMENU MENU_FILE "~File" -/* ba1 -5 */ +/* ba1 -5 Generazione dischetti */ MENUBAR MENU_BAR(5) MENU MENU_BAR(5) - SUBMENU MENU_FILE "~File" + SUBMENU MENU_FILE "~File" + +/* ba1 -6 Installazione dischetti */ +MENUBAR MENU_BAR(6) + +MENU MENU_BAR(6) + SUBMENU MENU_FILE "~File" diff --git a/ba/ba1600.cpp b/ba/ba1600.cpp index b596d2e34..6aed9a920 100755 --- a/ba/ba1600.cpp +++ b/ba/ba1600.cpp @@ -1,21 +1,129 @@ +#include + #include -#include +#include #include +#include +#include #include #include "ba1.h" #include "ba1600.h" +#include "ba1600a.h" /////////////////////////////////////////////////////////// // Configurazione per installazione /////////////////////////////////////////////////////////// -class TInstall_ini : public TConfig -{ -public: - TInstall_ini() : TConfig("install.ini") { } - virtual ~TInstall_ini() { } -}; +int TInstall_ini::build_list(const TString& module, TString_array& a, const char* sommario) +{ + CHECKS(module.len() >= 2, "Bad module ", (const char*)module); + + TConfig* sum = NULL; + if (sommario) + sum = new TConfig(sommario, module); + + TToken_string tmp; + for (int sub = 0; ; sub++) + { + TString16 paragraph = module; + if (module[2] == '\0') // Ho specificato un modulo principale + paragraph << sub; + + if (set_paragraph(paragraph)) + { + for (int index = 0; exist("File", index); index++) + { + tmp = get("File", NULL, index); + if (sum) + sum->set("File", tmp, paragraph, TRUE, index); + tmp.add(paragraph); + tmp.lower(); + a.add(tmp); + } + } + else + break; + + 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) +{ + build_list(module, a, sommario); + TAuto_token_string altri(get("Moduli", module)); + for (const char* mod = altri.get(0); mod; mod = altri.get()) + { + const TString16 submodule = mod; + if (!submodule.blank()) + build_list(submodule, a, sommario); + } + return a.items(); +} + +void TInstall_ini::copy_paragraph(const char* module, const char* summary) +{ + TConfig sum(summary, module); + TAssoc_array& ass = (TAssoc_array&)list_variables(module); + ass.restart(); + for (THash_object* ho = ass.get_hashobj(); ho; ho = ass.get_hashobj()) + { + const char* key = ho->key(); + const TString& str = (TString&)ho->obj(); + sum.set(key, str); + } +} + +void TInstall_ini::copy_module_paragraphs(const char* module, const char* summary) +{ + TString16 mod; + for (int sub = -1; ; sub++) + { + mod = module; + if (sub >= 0) mod << sub; + if (set_paragraph(mod)) + copy_paragraph(module, summary); + else + break; + } + + TAuto_token_string modules(get("Moduli", module)); + for (const char* m = modules.get(0); m; m = modules.get()) + { + mod = m; + if (!mod.blank()) + copy_paragraph(mod, summary); + } +} + +/////////////////////////////////////////////////////////// +// 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("|;,!^&", *s) != NULL) + { + separator(*s); + break; + } + } + + return *this; +} /////////////////////////////////////////////////////////// // Maschera modulo @@ -24,13 +132,207 @@ public: class TModule_mask : 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 link_handler(TMask_field& f, KEY k); + + bool find(const TString& name) const; + bool kill_missing(const char* name, bool update); public: - TModule_mask(const TString& module); + void load(const char* module); + void save(); + + TModule_mask(); virtual ~TModule_mask() { } }; +// Cerca un file nello sheet principale +bool TModule_mask::find(const TString& name) const +{ + TSheet_field& sf = sfield(F_SHEET); + for (int m = sf.items()-1; m >= 0; m--) + { + if (name.compare(sf.row(m).get(0), -1, TRUE) == 0) + break; + } + return m >= 0; +} + +// Toglie il file dallo sheet dei mancanti +bool TModule_mask::kill_missing(const char* name, bool update) +{ + TSheet_field& miss = sfield(F_MISSING); + for (int m = miss.items()-1; m >= 0; m--) + { + if (miss.row(m).compare(name, -1, TRUE) == 0) + { + miss.destroy(m, update); + break; + } + } + return m >= 0; +} + +bool TModule_mask::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(); + + TString16 module; + module << sf.mask().get(F_MODULE) << '0'; + + if (items > 0) + { + TModule_mask& msk = (TModule_mask&)sf.mask(); + + 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 (!msk.find(file)) + { + TToken_string& row = sf.row(found ? -1 : r); + row = file; + 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) << '0'; + + TToken_string& row = sf.row(r); + row.add(module, 1); + } + break; + default: + break; + } + return ok; +} + +bool TModule_mask::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 (int i = 0; i < sf.items(); i++) + { + TToken_string& newrow = sheet.row(-1); + newrow = sf.row(i); + TString16 submod = newrow.left(2); + submod << '0'; + newrow.add(submod); + } + sf.destroy(); + sf.force_update(); + sheet.force_update(); + ok = FALSE; + } + return ok; +} + +bool TModule_mask::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 perrcorso %s", + start.get_buffer()); + } + } + } + + if (k = K_TAB && f.focusdirty()) + { + TModule_mask& msk = (TModule_mask&)f.mask().get_sheet()->mask(); + msk.kill_missing(f.get(), TRUE); + } + + return TRUE; +} + bool TModule_mask::link_handler(TMask_field& f, KEY k) { if (k == K_SPACE) @@ -56,94 +358,108 @@ bool TModule_mask::link_handler(TMask_field& f, KEY k) return TRUE; } +void TModule_mask::load(const char* module) +{ + TWait_cursor hourglass; + set(F_MODULE, module); -TModule_mask::TModule_mask(const TString& module) - : TMask("ba1600b") -{ TInstall_ini ini; - TString paragraph, file; - TSheet_field& s = sfield(F_SHEET); - for (int sub = 0; ; sub++) - { - paragraph = module; - paragraph << sub; - if (ini.set_paragraph(paragraph)) - { - for (int index = 0; ini.exist("File", index); index++) - { - file = ini.get("File", NULL, index); - file.lower(); - TToken_string& row = s.row(-1); - row = file; - row.add(paragraph); - } - } - else - break; - } - - TToken_string externals(ini.get("Esterni", module), ' '); - for (TString16 e = externals.get(0); !e.blank(); e = externals.get()) - { - if (ini.set_paragraph(e)) - { - for (int index = 0; ini.exist("File", index); index++) - { - file = ini.get("File", NULL, index); - file.lower(); - TToken_string& row = s.row(-1); - row = file; - row.add(e); - s.disable_cell(s.items()-1, -1); - } - } - else - break; - } - - TSheet_field& miss = sfield(F_MISSING); - miss.disable(); // Read-only sheet - TMask& sm = miss.sheet_mask(); - sm.set_handler(100, link_handler); + ini.build_list(module, s.rows_array()); + s.rows_array().sort(); TFilename mask; mask << module << "*.*"; + TSheet_field& miss = sfield(F_MISSING); TString_array& arr = miss.rows_array(); list_files(mask, arr); - const char* goodext[] = { "exe", "msk", "frm", "rpt", NULL }; + const char* bad_ext[] = { "bsc", "mak", "obj", "pdb", "rc", + "res", "sbr", "vcw", "wsp", NULL }; for (int index = arr.items()-1; index >= 0; index--) - { - bool keep = FALSE; + { mask = arr.row(index); mask.lower(); - const TString16 ext = mask.ext(); - for (int e = 0; goodext[e]; e++) - { - if (ext.compare(goodext[e], -1, TRUE) == 0) - { - TString_array& sarr = s.rows_array(); - for (int i = sarr.items()-1; i >= 0; i--) - { - if (mask.compare(sarr.row(i).get(0), -1, TRUE) == 0) - break; - } - keep = i < 0; + + bool ok = TRUE; + for (int e = 0; bad_ext[e]; e++) + { + if (ext.compare(bad_ext[e], -1, TRUE) == 0) + { + ok = FALSE; break; - } + } } - if (keep) + if (ok) + { + TString_array& sarr = s.rows_array(); + for (int i = sarr.items()-1; i >= 0; i--) + { + if (mask.compare(sarr.row(i).get(0), -1, TRUE) == 0) + break; + } + ok = i < 0; + } + + if (ok) arr.row(index) = mask; else arr.destroy(index); } - arr.pack(); - miss.force_update(); + arr.sort(); +} + +void TModule_mask::save() +{ + TWait_cursor hourglass; + TSheet_field& sheet = sfield(F_SHEET); + + TInstall_ini ini; + int index; + + const TString16 module = get(F_MODULE); + for (index = 0; ; index++) + { + TString16 sub; sub << module << index; + if (ini.set_paragraph(sub)) + { + TAssoc_array& list = (TAssoc_array&)ini.list_variables(); + list.destroy(); + } + else + break; + } + + TString tmp; + index = 0; + for (int r = 0; r < sheet.items(); r++) + { + TToken_string& row = sheet.row(r); + TString16 sub = row.get(1); + if (isdigit(sub[0]) || sub.left(2) == module) + { + tmp = row.get(0); + ini.set("File", tmp, sub, TRUE, index++); + } + } +} + + +TModule_mask::TModule_mask() + : TMask("ba1600b") +{ + TSheet_field& s = sfield(F_SHEET); + s.set_notify(sheet_notify); + s.sheet_mask().set_handler(S_FILE, file_handler); + + TSheet_field& miss = sfield(F_MISSING); + miss.set_notify(missing_notify); + miss.disable(); // Read-only sheet + miss.sheet_mask().set_handler(100, link_handler); } /////////////////////////////////////////////////////////// @@ -154,8 +470,17 @@ class TFascicolator_mask : public TMask { protected: static bool list_handler(TMask_field& f, KEY k); - + static bool save_handler(TMask_field& f, KEY k); + + bool zip_file(const char* archive, const char* file) const; + int split_file(const TFilename& file, long size) const; + bool move_file(const TFilename& file, const char* dir) const; + bool zip_module(const TString& module) const; + public: + void load(); + void save(); + TFascicolator_mask(); virtual ~TFascicolator_mask() { } }; @@ -166,84 +491,340 @@ bool TFascicolator_mask::list_handler(TMask_field& f, KEY k) { const TMask& m = f.mask(); const TString& module = m.get(S_MODULE); - - TModule_mask mm(module); + TModule_mask mm; + mm.load(module); if (mm.run() == K_ENTER) - { - TInstall_ini ini; - int index; - for (index = 0; ; index++) - { - TString16 sub; sub << module << index; - if (ini.set_paragraph(sub)) - { - TAssoc_array& list = (TAssoc_array&)ini.list_variables(); - list.destroy(); - } - else - break; - } - - TSheet_field& sheet = mm.sfield(F_SHEET); - index = 0; - for (int r = sheet.items()-1; r >= 0; r--) - { - if (!sheet.cell_disabled(r, 0)) - { - TToken_string& row = sheet.row(r); - TString16 sub = row.get(1); - if (isdigit(sub[0]) || sub.left(2) == module) - { - if (isdigit(sub[0])) - sub.insert(module, 0); - ini.set("File", row.get(0), sub, TRUE, index++); - } - } - } - } + mm.save(); } return TRUE; } +bool TFascicolator_mask::save_handler(TMask_field& f, KEY k) +{ + if (k == K_SPACE) + { + TMask& m = f.mask(); + const TString& module = m.get(S_MODULE); + { + TInstall_ini ini; + ini.set_paragraph(module); + ini.set("Versione", m.get(S_VERSION)); + 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)); + } + + TFascicolator_mask& fm = (TFascicolator_mask&)m.get_sheet()->mask(); + fm.zip_module(module); + } + return TRUE; +} + +void TFascicolator_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 (int m = modules.items()-1; m >= 0; m--) + { + const TString& module = modules.row(m); + if (module.len() == 2) + { + TToken_string& row = s.row(-1); + ini.set_paragraph(module); + row = ini.get("Descrizione"); + row.add(module); + + tmp = ini.get("Versione"); + 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); + } + } + s.rows_array().sort(); +} + +void TFascicolator_mask::save() +{ + TSheet_field& s = sfield(F_SHEET); + TProgind pi(s.items(), "Salvataggio in corso...", FALSE, TRUE); + + TInstall_ini ini; + + ini.set("DiskSize", get(F_DISKSIZE)); + ini.set("DiskPath", get(F_DISKPATH)); + + TString tmp; + for (int r = s.items()-1; r >= 0; r--) + { + pi.addstatus(1); + TToken_string& row = s.row(r); + + 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("Data", tmp); + + tmp = row.get(); + ini.set("Moduli", tmp); + + tmp = row.get(); + ini.set("PreProcess", tmp); + + tmp = row.get(); + ini.set("PostProcess", tmp); + } + } +} + +bool TFascicolator_mask::zip_file(const char* archive, const char* file) const +{ + TWait_cursor hourglass; + TFilename cmd(120); + cmd << "zip.pif " << archive << ' ' << file; + TExternal_app app(cmd); + int err = app.run(FALSE, FALSE, FALSE, FALSE); + return err == 0; +} + +bool TFascicolator_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) + { + int disk = 0; + if (dest[1] == ':') + { + const char letter = toupper(dest[0]); + disk = 'A' - letter + 1; + } + struct _diskfree_t drive; + _dos_getdiskfree(disk, &drive); + + const unsigned requested_clusters = unsigned(filesize / drive.sectors_per_cluster / drive.bytes_per_sector) + 1; + space_ok = requested_clusters <= drive.avail_clusters; + if (!space_ok) + { + TString msg(128); + msg << "Lo spazio sull'unita' e' insufficiente"; + if (disk == 1 || disk == 2) + { + 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 scrittura del file %s.\nSi desidera riprovare?", + (const char*)file)); + user_abort = TRUE; + } + } while (!write_ok && !user_abort); + + return write_ok; +} + +int TFascicolator_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 << " " << 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; + } + + if (disks > 1) + ::remove(archive); + } + + return disks; +} + +bool TFascicolator_mask::zip_module(const TString& main_module) const +{ + TString_array arr; + TInstall_ini ini; + + TFilename sommario; sommario.tempdir(); + sommario.add(main_module); + sommario << "inst.ini"; // Nome del file sommario completo + + ini.build_complete_list(main_module, arr, sommario); + if (arr.items() == 0) + { + ::remove(sommario); + return error_box("Nessun file da compattare"); + } + + TFilename archivio(sommario); + archivio.ext("zip"); // Nome del file archivio completo + + bool aborted = FALSE; + TString msg(80); + msg << "Creazione del file " << archivio << " ..."; + TProgind pi(arr.items(), msg, TRUE, TRUE); + TFilename cmd; + for (int i = arr.items()-1; i >= 0; i--) + { + pi.addstatus(1); + cmd << ' ' << arr.row(i).get(0); + if (cmd.len() > 80) + { + zip_file(archivio, cmd); + cmd.cut(0); + } + if (pi.iscancelled()) + { + aborted = TRUE; + break; + } + } + if (cmd.len() > 0 && !aborted) + zip_file(archivio, cmd); + + msg.cut(0); + msg << "Separazione del file " << archivio << " ..."; + pi.set_text(msg); + + 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.copy_paragraph(main_module, sommario); // Aggiorna sommario + + // Se non specifico un path ho gia' finito + const TFilename path = get(F_DISKPATH); + if (path.blank()) + return TRUE; + + const char drive = toupper(path[0]); + const bool floppy = (drive == 'A' || drive == 'B') && path[1] == ':'; + + for (int d = 1; d <= disks && !aborted; d++) + { + if (floppy) + message_box("Inserire il disco %d di %d nell'unita' %c:", d, disks, drive); + + // Costruisco il nome del file da copiare su dischetto + TFilename src(archivio); + if (d > 1 || disks > 1) + { + 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(); + } + + return TRUE; +} + TFascicolator_mask::TFascicolator_mask() : TMask("ba1600a") { TSheet_field& s = sfield(F_SHEET); TMask& m = s.sheet_mask(); m.set_handler(S_LIST, list_handler); - - TScanner scanner("prassi.aut"); - TString tmp; - - TInstall_ini ini; - - for (int modulo = 0; ;modulo++) - { - const TString& lin = scanner.line(); - if (lin.empty()) - break; - TToken_string& row = s.row(modulo); - tmp = lin.left(2); - row = lin.mid(3); - row.add(tmp); - - if (tmp != "xx") - { - ini.set_paragraph(tmp); - - tmp = ini.get("Versione"); - row.add(tmp.left(2)); - row.add(tmp.mid(2)); - - tmp = ini.get("Data"); - row.add(tmp); - - tmp = ini.get("Moduli"); - row.add(tmp); - } - else - s.disable_cell(modulo, -1); - } + m.set_handler(100, save_handler); } /////////////////////////////////////////////////////////// @@ -260,12 +841,14 @@ protected: void TFascicolator::main_loop() { TFascicolator_mask m; - m.run(); + m.load(); + if (m.run() == K_ENTER) + m.save(); } int ba1600(int argc, char* argv[]) { TFascicolator app; - app.run(argc, argv, "The Fascicolator"); + app.run(argc, argv, "Megascicolator"); return 0; } diff --git a/ba/ba1600.h b/ba/ba1600.h index 4781287ce..80504438d 100755 --- a/ba/ba1600.h +++ b/ba/ba1600.h @@ -1,5 +1,39 @@ -#define F_SHEET 201 -#define F_MISSING 202 +#ifndef __BA1600_H +#define __BA1600_H -#define S_MODULE 102 -#define S_LIST 200 \ No newline at end of file +#ifndef __CONFIG_H +#include +#endif + +class TInstall_ini : public TConfig +{ +public: + int build_list(const TString& m, TString_array& a, const char* s = NULL); + int build_complete_list(const TString& m, TString_array& a, const char* s = NULL); + + void copy_paragraph(const char* module, const char* summary); + void copy_module_paragraphs(const char* module, const char* summary); + + static const char* default_name() { return "install.ini"; } + + TInstall_ini() : TConfig("install.ini", "Main") { } + TInstall_ini(const char* path) : TConfig(path, "Main") { } + virtual ~TInstall_ini() { } +}; + +// Mitica token string che sceglie da sola il separatore +class TAuto_token_string : public TToken_string +{ +protected: + TAuto_token_string& create(const char* ts); + +public: + TAuto_token_string& operator=(const char* ts) { return create(ts); } + TAuto_token_string& operator=(const TString& ts) { return create(ts); } + TAuto_token_string& operator=(const TToken_string& ts) { return create(ts); } + TAuto_token_string& operator=(const TAuto_token_string& ts) { return create(ts); } + TAuto_token_string(const char* ts) { create(ts); } + virtual ~TAuto_token_string() { } +}; + +#endif diff --git a/ba/ba1600a.h b/ba/ba1600a.h new file mode 100755 index 000000000..9879e1907 --- /dev/null +++ b/ba/ba1600a.h @@ -0,0 +1,19 @@ +#ifndef __BA1600A_H +#define __BA1600A_H + +#define F_DISKSIZE 201 +#define F_DISKPATH 202 +#define F_SHEET 203 +#define F_MISSING 204 +#define F_MODULE 205 + +#define S_FILE 101 +#define S_MODULE 102 +#define S_VERSION 103 +#define S_DATE 104 +#define S_EXTERN 105 +#define S_PREPROCESS 106 +#define S_POSTPROCESS 107 +#define S_LIST 200 + +#endif diff --git a/ba/ba1600a.uml b/ba/ba1600a.uml index 88769329d..b1023d58d 100755 --- a/ba/ba1600a.uml +++ b/ba/ba1600a.uml @@ -1,93 +1,114 @@ -#include "ba1600.h" +#include "ba1600a.h" TOOLBAR "" 0 20 0 2 BUTTON DLG_OK 10 2 BEGIN - PROMPT -13 -11 "" + PROMPT -12 -11 "" END BUTTON DLG_QUIT 10 2 BEGIN - PROMPT -33 -11 "" + PROMPT -22 -11 "" END ENDPAGE PAGE "Generazione dischetti" -1 -1 78 20 +GROUPBOX DLG_NULL 78 3 +BEGIN + PROMPT 1 0 "Parametri unita'" +END + +NUMBER F_DISKSIZE 5 +BEGIN + PROMPT 2 1 "Dimensione (K) " +END + +STRING F_DISKPATH 50 40 +BEGIN + PROMPT 25 1 "Percorso " +END + SPREADSHEET F_SHEET BEGIN - PROMPT 1 1 "" + PROMPT 1 4 "" ITEM "Modulo@30" - ITEM "Codice" - ITEM "Anno" - ITEM "N." + ITEM "Cod." + ITEM "Versione" ITEM "Rilascio" ITEM "Moduli esterni@30" + ITEM "Pre-processing@25" + ITEM "Post-processing@25" END ENDPAGE ENDMASK -PAGE "Modulo" -1 -1 42 7 +PAGE "Modulo" -1 -1 52 8 -STRING 101 30 +STRING 101 36 BEGIN - PROMPT 1 1 "Modulo " + PROMPT 14 1 "" FLAGS "D" END STRING S_MODULE 2 BEGIN - PROMPT 1 0 "Codice " + PROMPT 1 1 "Modulo " FLAGS "D" END -NUMBER 103 2 +STRING S_VERSION 6 BEGIN PROMPT 1 2 "Versione " END -NUMBER 104 2 +DATE S_DATE BEGIN - PROMPT 14 2 "" - FLAGS "Z" -END - -DATE 105 -BEGIN - PROMPT 21 2 "Rilascio " + PROMPT 31 2 "Rilascio " END -STRING 106 30 +STRING S_EXTERN 50 40 BEGIN PROMPT 1 3 "Esterni " END -BUTTON S_LIST +STRING S_PREPROCESS 50 33 BEGIN - PROMPT -13 4 "Lista file" + PROMPT 1 4 "Pre-processing " +END + +STRING S_POSTPROCESS 50 33 +BEGIN + PROMPT 1 5 "Post-processing " END BUTTON DLG_OK 10 2 BEGIN - PROMPT -13 -1 "" + PROMPT -14 -1 "" END BUTTON 100 10 2 BEGIN - PROMPT -23 -1 "" + PROMPT -24 -1 "" PICTURE BMP_SAVEREC PICTURE BMP_SAVERECDN END +BUTTON S_LIST 10 2 +BEGIN + PROMPT -34 -1 "Lista file" +END + BUTTON DLG_CANCEL 10 2 BEGIN - PROMPT -33 -1 "" + PROMPT -44 -1 "" END + ENDPAGE ENDMASK diff --git a/ba/ba1600b.uml b/ba/ba1600b.uml index eb9773083..cda2eccc6 100755 --- a/ba/ba1600b.uml +++ b/ba/ba1600b.uml @@ -1,4 +1,4 @@ -#include "ba1600.h" +#include "ba1600a.h" TOOLBAR "" 0 20 0 2 @@ -16,11 +16,17 @@ ENDPAGE PAGE "Lista" -1 -1 78 20 +STRING F_MODULE 2 +BEGIN + PROMPT 1 0 "Modulo " + FLAGS "D" +END + SPREADSHEET F_SHEET 46 BEGIN PROMPT 1 1 "" - ITEM "File@20" - ITEM "Sottomodulo" + ITEM "File@32" + ITEM "Mod." END SPREADSHEET F_MISSING 20 @@ -34,11 +40,12 @@ ENDPAGE ENDMASK -PAGE "File" -1 -1 42 5 +PAGE "File" -1 -1 52 5 -STRING 101 30 +STRING 101 35 BEGIN PROMPT 1 1 "File " + FLAGS "B" END STRING S_MODULE 3 @@ -48,12 +55,18 @@ END BUTTON DLG_OK 10 2 BEGIN - PROMPT -12 -1 "" + PROMPT -13 -1 "" +END + +BUTTON DLG_DELREC 10 2 +BEGIN + PROMPT -23 -1 "~Scollega" + PICTURE BMP_DELREC END BUTTON DLG_CANCEL 10 2 BEGIN - PROMPT -22 -1 "" + PROMPT -33 -1 "" END ENDPAGE @@ -81,4 +94,4 @@ END ENDPAGE ENDMASK - \ No newline at end of file + diff --git a/ba/ba1700.cpp b/ba/ba1700.cpp new file mode 100755 index 000000000..9aa80d1f3 --- /dev/null +++ b/ba/ba1700.cpp @@ -0,0 +1,416 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include "ba1.h" +#include "ba1600.h" +#include "ba1700a.h" + +HIDDEN int compare_version(const TString& v1, const TString& v2) +{ + TString16 ver1(v1), ver2(v2); + ver1.trim(); + if (ver1.len() == 4) + ver1.insert((v1[0] == '9') ? "19" : "20", 0); + ver2.trim(); + if (ver2.len() == 4) + ver2.insert((v2[0] == '9') ? "19" : "20", 0); + return ver1.compare(ver2, -1, TRUE); +} + +/////////////////////////////////////////////////////////// +// Maschera principale +/////////////////////////////////////////////////////////// + +class TInstaller_mask : public TMask +{ +protected: + static bool update_handler(TMask_field& fld, KEY key); + static bool path_handler(TMask_field& fld, KEY key); + static bool sheet_notify(TSheet_field& s, int r, KEY k); + static bool install_handler(TMask_field& fld, KEY key); + + bool add_module(TConfig& ini, const TString& module) const; + void update_version(); + + bool do_process(TAuto_token_string& commands) const; + bool pre_process(TInstall_ini& ini, const char* module) const; + bool post_process(TInstall_ini& ini, const char* module) const; + +public: + bool autoload(); + bool install(const TString& module); + + TInstaller_mask(); + virtual ~TInstaller_mask() { } +}; + +// Copia nello sheet i dati di un modulo prendendoli da un .ini +bool TInstaller_mask::add_module(TConfig& ini, const TString& module) const +{ + bool ok = ini.set_paragraph(module); + if (ok) + { + TSheet_field& sheet = sfield(F_SHEET); + TToken_string& row = sheet.row(-1); + row = ini.get("Descrizione"); + row.add(module); + row.add(ini.get("Versione")); + row.add(ini.get("Data")); + } + return ok; +} + +void TInstaller_mask::update_version() +{ + TInstall_ini ini; + + TSheet_field& sheet = sfield(F_SHEET); + for (int m = sheet.items()-1; m >= 0; m--) + { + TToken_string& row = sheet.row(m); + const TString16 module = row.get(1); + ini.set_paragraph(module); + + const TString newver = row.get(2); + const TString oldver = ini.get("Versione"); + row.add(oldver, 4); + row.add(ini.get("Data"), 5); + + const int cmp = compare_version(newver, oldver); + if (cmp > 0) + sheet.set_back_and_fore_color(FOCUS_BACK_COLOR, FOCUS_COLOR, m); + if (cmp == 0) + sheet.set_back_and_fore_color(NORMAL_BACK_COLOR, NORMAL_COLOR, m); + if (cmp < 0) + sheet.set_back_and_fore_color(DISABLED_BACK_COLOR, NORMAL_COLOR, m); + } + sheet.force_update(); +} + +// Cerca nel percorso specificato sulla maschera tutti i possibili files .ini +// utilizzabili per un'installazione e li inserisce nello spreadsheet +bool TInstaller_mask::autoload() +{ + const TString& path = get(F_PATH); + if (!fexist(path)) + return error_box("Specificare un percorso valido"); + + TWait_cursor hourglass; + TSheet_field& sheet = sfield(F_SHEET); + + sheet.destroy(); + + TFilename ininame; + ininame = path; + ininame.add(TInstall_ini::default_name()); + + TString_array modules; + + if (fexist(ininame)) + { + TInstall_ini ini(ininame); + ini.list_paragraphs(modules); + for (int i = modules.items()-1; i >= 0; i--) + { + const TString& module = modules.row(i); + if (module.len() == 2 && module != "xx") + add_module(ini, module); + } + } + else + { + ininame = path; + ininame.add("??inst.ini"); + const int files = list_files(ininame, modules); + for (int m = files-1; m >= 0; m--) + { + TString& ininame = modules.row(m); + ininame.lower(); + const int pos = ininame.find("inst.ini"); + CHECKS(pos > 2, "Invalid installation configuration: ", (const char*)ininame); + const TString16 module = ininame.mid(pos-2, 2); + TConfig ini(ininame, module); + add_module(ini, module); + } + } + + sheet.rows_array().sort(); + const bool ok = sheet.items() > 0; + if (ok) + update_version(); + else + sheet.error_box("Non e' stato trovato nessun modulo da installare\n" + "in %s", (const char*)path); + + return ok; +} + +bool TInstaller_mask::do_process(TAuto_token_string& commands) const +{ + bool ok = TRUE; + TFilename cmd; + for (const char* c = commands.get(0); c && ok; c = commands.get()) + { + cmd = c; + if (!cmd.blank()) + { + TWait_cursor hourglass; + TExternal_app app(cmd); + ok = app.run() == 0; + } + } + return ok; +} + +bool TInstaller_mask::pre_process(TInstall_ini& ini, const char* module) const +{ + TAuto_token_string commands(ini.get("PreProcess", module)); + return do_process(commands); +} + +bool TInstaller_mask::post_process(TInstall_ini& ini, const char* module) const +{ + TAuto_token_string commands(ini.get("PostProcess", module)); + return do_process(commands); +} + +bool TInstaller_mask::install(const TString& module) +{ + TWait_cursor hourglass; + bool ok = FALSE; + + const TString& path = get(F_PATH); + TFilename ininame = path; + ininame.add(module); + ininame << "inst.ini"; + + if (fexist(ininame)) + { + TInstall_ini ini(ininame); + const int dischi = ini.get_int("Dischi", module); + ok = dischi > 0; + + if (ok) + ok = pre_process(ini, module); + + TProgind pi(dischi, "Decompressione in corso...", FALSE, TRUE); + + TFilename cmdline; + for (int d = 1; d <= dischi && ok; d++) + { + cmdline = ininame.path(); + cmdline.add(module); + cmdline << "inst"; + if (dischi > 1) cmdline << d; + cmdline.ext("zip"); + + ok = fexist(cmdline); + while (!ok) + { + message_box("Inserire il disco %d di %d del modulo\n%s", + d, dischi, (const char*)ini.get("Descrizione")); + ok = fexist(cmdline); + if (!ok) + { + if (!yesno_box("Impossibile trovare %s\nSi desidera riprovare?", + (const char*)cmdline)) + break; + } + } + + if (ok) + { + struct _diskfree_t drive; + _dos_getdiskfree(0, &drive); + const long required = fsize(cmdline) * (dischi-d+1) * 3; + const unsigned requested_clusters = unsigned(required / drive.sectors_per_cluster / drive.bytes_per_sector) + 1; + if (requested_clusters >= drive.avail_clusters) + { + ok = yesno_box("Lo spazio su disco potrebbe essere insufficiente:\n" + "Si desidera continuare ugualmente?"); + } + } + + if (ok) + { + TWait_cursor hourglass; + cmdline.insert("unzip.pif -o ", 0); + TExternal_app app(cmdline); + ok = app.run(FALSE, FALSE, FALSE, FALSE) == 0; + pi.addstatus(1); + } + } + + if (ok) + { + post_process(ini, module); + ini.copy_module_paragraphs(module, ini.default_name()); + + } + } + else + { + ininame = path; + ininame.add(TInstall_ini::default_name()); + ok = fexist(ininame); + if (ok) + { + TInstall_ini ini(ininame); + TString_array list; + const int files = ini.build_complete_list(module, list); + if (files > 0) + { + pre_process(ini, module); + + TProgind pi(files, "Copia in corso...", FALSE, TRUE); + TFilename src, dst; + for (int f = 0; f < files && ok; f++) + { + pi.addstatus(1); + dst = list.row(f).get(0); + src = path; + src.add(dst); + ok = fcopy(src, dst); + } + if (ok) + { + ini.copy_module_paragraphs(module, ini.default_name()); + post_process(ini, module); + } + } + } + } + + if (ok) + { + TInstall_ini ini; + ini.set("DiskPath", path); + ini.set("Data", TDate(TODAY), module); + } + update_version(); + + return ok; +} + +bool TInstaller_mask::update_handler(TMask_field& fld, KEY key) +{ + if (key == K_SPACE) + { + TInstaller_mask& m = (TInstaller_mask&)fld.mask(); + m.autoload(); + } + return TRUE; +} + +bool TInstaller_mask::path_handler(TMask_field& fld, KEY key) +{ + bool ok = TRUE; + if (key == K_TAB && fld.focusdirty()) + { + TString path = fld.get(); + if (path.len() == 2 && isalpha(path[0]) && path[1] == ':') + { + path << SLASH; + fld.set(path); + } + if (fexist(path)) + update_handler(fld, K_SPACE); + else + ok = fld.error_box("Specificare un percorso valido"); + } + return ok; +} + +bool TInstaller_mask::sheet_notify(TSheet_field& s, int r, KEY k) +{ + bool ok = TRUE; + if (k == K_INS) // Impedisci l'inserimento di nuove righe + ok = FALSE; + return ok; +} + +bool TInstaller_mask::install_handler(TMask_field& fld, KEY key) +{ + bool ok = TRUE; + if (key == K_SPACE) + { + TMask& m = fld.mask(); + const TString& modulo = m.get(S_MODULE); + const TString& newver = m.get(S_NEW_VERSION); + const TString& oldver = m.get(S_CUR_VERSION); + + const int cmp = compare_version(oldver, newver); + if (cmp < 0) + ok = yesno_box("Si desidera installare la versione %s?", (const char*)newver); + if (cmp == 0) + ok = yesno_box("Si desidera reinstallare la versione %s?", (const char*)newver); + if (cmp > 0) + ok = yesno_box("Si desidera ritornare alla versione %s?\n" + "Attenzione: non e' garantito il corretto\n" + "funzionamento di tutti i programmi!", (const char*)oldver); + if (ok) + { + TInstaller_mask& im = (TInstaller_mask&)m.get_sheet()->mask(); + im.install(modulo); + } + } + return ok; +} + +TInstaller_mask::TInstaller_mask() + : TMask("ba1700a") +{ + set_handler(F_PATH, path_handler); + set_handler(F_UPDATE, update_handler); + TSheet_field& sheet = sfield(F_SHEET); + sheet.set_notify(sheet_notify); + sheet.disable(); + TMask& m = sheet.sheet_mask(); + m.set_handler(S_INSTALL, install_handler); + + TInstall_ini ini; + TFilename path = ini.get("DiskPath"); + set(F_PATH, path); + + const char lettera = toupper(path[0]); + const bool floppy = (path.len() > 1) && path[1] == ':' && + (lettera == 'A' || lettera == 'B'); + if (path.not_empty() && !floppy) + autoload(); + + DIRECTORY dir; + xvt_fsys_get_dir(&dir); + xvt_fsys_convert_dir_to_str(&dir, path.get_buffer(), path.size()); + set(F_CURPATH, path); +} + +/////////////////////////////////////////////////////////// +// Programma principale +/////////////////////////////////////////////////////////// + +class TInstaller : public TSkeleton_application +{ +protected: + virtual bool use_files() const { return FALSE; } + virtual void main_loop(); +}; + +void TInstaller::main_loop() +{ + TInstaller_mask m; + m.load(); + m.run(); +} + +int ba1700(int argc, char* argv[]) +{ + TInstaller app; + app.run(argc, argv, "Installer"); + return 0; +} diff --git a/ba/ba1700a.h b/ba/ba1700a.h new file mode 100755 index 000000000..05766255f --- /dev/null +++ b/ba/ba1700a.h @@ -0,0 +1,11 @@ +#define F_PATH 201 +#define F_CURPATH 202 +#define F_UPDATE 203 +#define F_SHEET 204 + +#define S_INSTALL 100 +#define S_MODULE 102 +#define S_NEW_VERSION 103 +#define S_NEW_DATE 104 +#define S_CUR_VERSION 105 +#define S_CUR_DATE 106 \ No newline at end of file diff --git a/ba/ba1700a.uml b/ba/ba1700a.uml new file mode 100755 index 000000000..387d6dd26 --- /dev/null +++ b/ba/ba1700a.uml @@ -0,0 +1,104 @@ +#include "ba1700a.h" + +TOOLBAR "" 0 20 0 2 + +BUTTON F_UPDATE 10 2 +BEGIN + PROMPT -12 -11 "Aggiorna" +END + +BUTTON DLG_QUIT 10 2 +BEGIN + PROMPT -22 -11 "" +END + +ENDPAGE + +PAGE "Installazione" -1 -1 78 20 + +STRING F_PATH 45 +BEGIN + PROMPT 1 1 "Percorso da cui installare " +END + +STRING F_CURPATH 45 +BEGIN + PROMPT 1 2 "Percorso in cui installare " + FLAGS "D" +END + +SPREADSHEET F_SHEET +BEGIN + PROMPT 1 3 "" + ITEM "Modulo@30" + ITEM "Cod." + ITEM "Versione\nda installare@13" + ITEM "Data\nRilascio@10" + ITEM "Versione\nInstallata@10" + ITEM "Data\nInstallazione@13" +END + +ENDPAGE + +ENDMASK + +PAGE "Modulo" -1 -1 52 10 + +GROUPBOX DLG_NULL 50 3 +BEGIN + PROMPT 1 0 "@bModulo" +END + +STRING 101 43 +BEGIN + PROMPT 6 1 "" +END + +STRING 102 2 +BEGIN + PROMPT 2 1 "" +END + +GROUPBOX DLG_NULL 50 3 +BEGIN + PROMPT 1 3 "@bVersione da installare" +END + +STRING 103 6 +BEGIN + PROMPT 2 4 "Versione " +END + +DATE 104 +BEGIN + PROMPT 34 4 "Data " +END + +GROUPBOX DLG_NULL 50 3 +BEGIN + PROMPT 1 6 "@bVersione installata" +END + +STRING 105 6 +BEGIN + PROMPT 2 7 "Versione " +END + +DATE 106 +BEGIN + PROMPT 34 7 "Data " +END + +BUTTON DLG_CANCEL 10 2 +BEGIN + PROMPT -12 -1 "" +END + +BUTTON 100 10 2 +BEGIN + PROMPT -22 -1 "Installa" +END + +ENDPAGE + +ENDMASK