From 5fac2edf5263c55e964d67375e3ac6ffdb2cf3ff Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Wed, 23 Sep 2026 08:46:53 +0200 Subject: [PATCH] Rilascia la 1.0.0: licenza, CHANGELOG e documentazione riallineata al codice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Versione portata a 1.0.0 (csproj, CLAUDE.md) e voce [1.0.0] nel CHANGELOG con tutto il lavoro dalla 0.9.0: setup per-utente, nuovo nome "PrepStep - Cevolani", DB fisso nella cartella di installazione, "Elimina CSV delle distinte", guide aggiornate. Nuova LICENSE proprietaria (Davide Grilli, tutti i diritti riservati), riportata anche in dell'exe e AppCopyright del setup. README: sequenza completa di comandi per generare il setup. Documentazione riallineata al codice dopo un controllo file per file: nomi delle fasi come nella UI, "File → Nuovo" che non cancella file, mappa dei file e test nel README, riferimenti ad AssiemeCompleto (non esiste più) e ruolo di CaricaCodiciNoti/CaricaCandidati in fase 4. Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 54 ++++++++++++++++++++++----------- CLAUDE.md | 7 +++-- LICENSE | 17 +++++++++++ PrepStep/GuidaForm.cs | 50 +++++++++++++++++++++++++----- PrepStep/PrepStep.csproj | 3 +- README.md | 62 ++++++++++++++++++++++++++------------ docs/architettura.md | 22 +++++++++----- docs/db-cad-index.md | 24 +++++++++------ docs/formato-asm-record.md | 6 ++-- docs/formato-asm.md | 13 ++++---- docs/guida-utente.md | 13 ++++---- installer/PrepStep.iss | 1 + 12 files changed, 192 insertions(+), 80 deletions(-) create mode 100644 LICENSE diff --git a/CHANGELOG.md b/CHANGELOG.md index f1892cd..6acadab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,31 +5,51 @@ Tutte le modifiche rilevanti di questo progetto sono documentate in questo file. Il formato segue [Keep a Changelog](https://keepachangelog.com/it/1.1.0/), e il progetto aderisce a [Semantic Versioning](https://semver.org/lang/it/). -## [Non rilasciato] +## [1.0.0] - 2026-09-23 + +Prima versione distribuita agli utenti tramite setup di installazione. ### Aggiunto +- Setup di installazione per-utente (`installer/PrepStep.iss`, Inno Setup 6): + `PrepStep-Setup-.exe` installa in `%LOCALAPPDATA%\Programs\PrepStep` senza diritti + di amministratore, crea nel menu Start i collegamenti al programma e al disinstallatore + (quello sul desktop è facoltativo) e registra l'app in "Impostazioni → App installate". +- Il setup, se l'app è già installata, chiede se aggiornarla/reinstallarla, disinstallarla o + uscire; con `/VERYSILENT` aggiorna senza chiedere. Aggiornando, database e impostazioni + restano. - "File → Elimina CSV delle distinte...": elimina i CSV generati dall'import, che altrimenti si - accumulano nella cartella di lavoro (uno per distinta). -- Guida utente e guida in-app: nuova sezione "Dove finiscono i file" (cartella di lavoro, - database, pulizia, come aprire la cartella nascosta in AppData); fase 1 allineata al DB - sempre nella cartella di installazione. - -- Setup di installazione per-utente (`installer/PrepStep.iss`, Inno Setup 6): installa in - `%LOCALAPPDATA%\Programs\PrepStep` senza diritti di amministratore, con collegamento nel - menu Start e disinstallazione dal menu Start, da "App installate" o rilanciando il setup (che, se l'app è - già installata, chiede se aggiornarla o disinstallarla). + accumulano nella cartella di lavoro (uno per distinta). Chiede conferma mostrando l'elenco + dei file; non tocca gli `.xls` del gestionale né `raw/`/`step/`. +- Guida utente e guida in-app: nuova sezione "Dove finiscono i file" (database, CSV, `raw/`, + `step/`, comandi di pulizia, come aprire la cartella nascosta in `AppData`, file che restano + dopo la disinstallazione). +- Licenza proprietaria (`LICENSE`, © 2026 Davide Grilli, tutti i diritti riservati), anche nei + metadati dell'exe e del setup. +- README: sequenza completa di comandi per generare il setup a ogni release. ### Modificato - Nome dell'app mostrato all'utente: da "Cevolani StepPrep" a "PrepStep - Cevolani" (titolo - finestra, guida, setup, menu Start). Aggiornando, il setup rimuove i collegamenti col vecchio - nome. -- Il database è sempre `cad_index.db` nella cartella di installazione: non viene più ricordato - l'ultimo DB aperto (`%AppData%/PrepStep/ultimo_db.txt` non è più usato) e "Apri DB..." vale - solo per la sessione. -- Senza una cartella di lavoro salvata si propone la cartella di installazione invece di quella - del DB. + finestra, guida, setup, menu Start, "App installate"). +- Il database è sempre `cad_index.db` nella cartella di installazione: all'avvio si carica + solo quello e "Aggiorna indice" lo crea lì se manca. "Apri DB..." carica un altro database + solo per la sessione corrente. +- La cartella di lavoro predefinita (se non ne è stata scelta una con "File → Scegli cartella + di lavoro...") è la cartella di installazione, invece della cartella del database. +- Guida utente: fase 1 riscritta per il database fisso; tolta la sezione di installazione (chi + legge la guida ha già il programma; le istruzioni restano nel `README.md`). +- Finestra Guida più grande (1000×680) e testo non più "da editor": niente cursore + lampeggiante, niente cursore a "I" e niente selezione col mouse. +- Documentazione riallineata al codice: nomi delle fasi come nella UI ("5. Verifica + completezza"), "File → Nuovo" che non cancella file su disco, mappa dei file e test nel + README, riferimenti a metodi non più esistenti (`AssiemeCompleto`) e ruolo di + `CaricaCodiciNoti`/`CaricaCandidati` in fase 4. + +### Rimosso + +- Memoria dell'ultimo database aperto (`%AppData%\PrepStep\ultimo_db.txt`) e ricerca di + `cad_index.db` nella cartella corrente. ## [0.9.0] - 2026-09-23 diff --git a/CLAUDE.md b/CLAUDE.md index 2cd9636..a215204 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co `PrepStep` è il nome tecnico del progetto (cartella, namespace, csproj, eseguibile `PrepStep.exe`); il nome mostrato all'utente finale è **PrepStep - Cevolani** (``/ `` in `PrepStep/PrepStep.csproj`, usato nel titolo della finestra insieme -alla versione, ``, attualmente `0.9.0`). È un'app Windows Forms (.NET 10, WinForms) che indicizza e permette di +alla versione, ``, attualmente `1.0.0`). È un'app Windows Forms (.NET 10, WinForms) che indicizza e permette di cercare i file CAD Pro-ENGINEER/Creo contenuti in tutte le cartelle di primo livello di un disco/share di rete (radice di default `X:\`), salvando i metadati in un DB SQLite locale (`cad_index.db`). Il flusso a valle (fasi 2-5, vedi sotto) prepara i file @@ -72,7 +72,8 @@ atteso). ## Architettura -Il programma è tutto in `PrepStep/` (nessun altro progetto nella solution). Dettaglio +Il programma è tutto in `PrepStep/` (accanto ci sono solo i test `PrepStep.Tests/`, gli +script `scripts/` e il setup `installer/`). Dettaglio completo file-per-file in [`docs/architettura.md`](docs/architettura.md); qui solo il flusso che conta per capire il prodotto. @@ -140,5 +141,5 @@ intercambiabili: - `ExtractCreoStrings.cs`/`BomViaDb.cs` usano `AssemblyComponentScanner` (euristica testuale, `docs/formato-asm.md`) e risolvono i sottoassiemi contro `cad_index.db`. - `CreoBom.cs` usa `AsmRecordReader` (parser esatto dei record binari, - `docs/formato-asm-record.md`, condiviso con la GUI in fase 4/5) e risolve i sottoassiemi + `docs/formato-asm-record.md`, condiviso con la GUI in fase 4) e risolve i sottoassiemi cercandoli in cartelle locali (`-p`), non contro `cad_index.db`. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d82e11e --- /dev/null +++ b/LICENSE @@ -0,0 +1,17 @@ +Copyright (c) 2026 Davide Grilli. Tutti i diritti riservati. + +Questo software, il codice sorgente, la documentazione e i file correlati ("il Software") +sono di proprietà esclusiva di Davide Grilli. + +Senza previa autorizzazione scritta del titolare è vietato copiare, modificare, unire, +pubblicare, distribuire, concedere in sublicenza o vendere copie del Software, in tutto o +in parte, e ricavarne opere derivate. + +L'uso del Software è consentito solo alle persone e alle organizzazioni espressamente +autorizzate dal titolare, e nei limiti di tale autorizzazione. + +IL SOFTWARE È FORNITO "COSÌ COM'È", SENZA GARANZIE DI ALCUN TIPO, ESPRESSE O IMPLICITE, +INCLUSE, SENZA LIMITAZIONE, LE GARANZIE DI COMMERCIABILITÀ, IDONEITÀ A UNO SCOPO +PARTICOLARE E NON VIOLAZIONE. IN NESSUN CASO IL TITOLARE SARÀ RESPONSABILE PER QUALSIASI +RECLAMO, DANNO O ALTRA RESPONSABILITÀ DERIVANTE DALL'USO DEL SOFTWARE O IN RELAZIONE AD +ESSO. diff --git a/PrepStep/GuidaForm.cs b/PrepStep/GuidaForm.cs index 251349e..20035ad 100644 --- a/PrepStep/GuidaForm.cs +++ b/PrepStep/GuidaForm.cs @@ -1,3 +1,5 @@ +using System.Runtime.InteropServices; + namespace PrepStep; /// Guida interattiva richiamabile da "Aiuto ▸ Guida" (F1): stessa guida completa di @@ -35,7 +37,7 @@ public class GuidaForm : Form "PrepStep - Cevolani prepara i file CAD Pro-ENGINEER/Creo da passare a Creo " + "Distributed Batch per l'esportazione STEP: indicizza i file di una share di rete " + "e guida attraverso 5 fasi, una alla volta, con \"Avanti\"/\"Indietro\".", - NotaTesto: "\"File ▸ Nuovo\" (Ctrl+N) azzera distinta/raw/verifica per ripartire " + + NotaTesto: "\"File ▸ Nuovo\" (Ctrl+N) azzera lo stato di distinta/raw/verifica per ripartire " + "con una nuova distinta base, senza dover ricaricare il database."), new("Dove finiscono i file", @@ -158,9 +160,10 @@ public class GuidaForm : Form NotaAttenzione: true), new("Ripartire da capo", - "Quando devi processare un'altra distinta, usa \"File ▸ Nuovo\" (Ctrl+N): azzera " + - "CSV, raw e verifica delle fasi 2-5 e riporta al passo 2, senza dover ricaricare " + - "il database o la cartella di lavoro (restano quelli già impostati in fase 1).", + "Quando devi processare un'altra distinta, usa \"File ▸ Nuovo\" (Ctrl+N): svuota " + + "le griglie e la verifica delle fasi 2-5 e riporta al passo 2, senza dover " + + "ricaricare il database né cambiare la cartella di lavoro. Non cancella nessun " + + "file su disco: CSV, \"raw\" e \"step\" restano.", NotaTesto: "Per ripulire le cartelle \"raw\" e \"step\" della cartella di lavoro " + "prima di un nuovo giro (senza toccare l'indice), usa \"File ▸ Pulisci raw e " + "step...\"; per eliminare i CSV che ogni distinta importata lascia nella " + @@ -170,8 +173,8 @@ public class GuidaForm : Form public GuidaForm() { Text = "Guida"; - ClientSize = new Size(780, 520); - MinimumSize = new Size(580, 400); + ClientSize = new Size(1000, 680); + MinimumSize = new Size(640, 440); StartPosition = FormStartPosition.CenterParent; Font = new Font("Segoe UI", 9.5f); try @@ -223,10 +226,11 @@ public class GuidaForm : Form colore, TextFormatFlags.VerticalCenter | TextFormatFlags.Left | TextFormatFlags.EndEllipsis); }; - var testo = new RichTextBox + var testo = new TestoSolaLettura { Dock = DockStyle.Fill, ReadOnly = true, + TabStop = false, BorderStyle = BorderStyle.None, BackColor = Color.White, Font = new Font(Font.FontFamily, 10f), @@ -310,4 +314,36 @@ public class GuidaForm : Form box.SelectionStart = 0; box.SelectionLength = 0; } + + /// RichTextBox da sola lettura che non si comporta come un editor: niente cursore + /// lampeggiante, niente cursore a "I" e niente selezione col mouse. I clic nell'area di testo + /// vengono ignorati (così non prende il fuoco e non mostra il caret); la barra di scorrimento + /// sta nell'area non-client e resta utilizzabile, la rotella scorre al passaggio del mouse. + private sealed class TestoSolaLettura : RichTextBox + { + private const int WM_SETFOCUS = 0x0007; + private const int WM_SETCURSOR = 0x0020; + private const int WM_LBUTTONDOWN = 0x0201; + private const int WM_LBUTTONDBLCLK = 0x0203; + private const int WM_RBUTTONDOWN = 0x0204; + + [DllImport("user32.dll")] + private static extern bool HideCaret(IntPtr hWnd); + + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case WM_LBUTTONDOWN or WM_LBUTTONDBLCLK or WM_RBUTTONDOWN: + return; + case WM_SETCURSOR: + Cursor.Current = Cursors.Arrow; + m.Result = 1; + return; + } + base.WndProc(ref m); + if (m.Msg == WM_SETFOCUS) + HideCaret(Handle); + } + } } diff --git a/PrepStep/PrepStep.csproj b/PrepStep/PrepStep.csproj index c1e8011..859c84b 100644 --- a/PrepStep/PrepStep.csproj +++ b/PrepStep/PrepStep.csproj @@ -11,7 +11,8 @@ PrepStep - Cevolani PrepStep - Cevolani Cevolani - 0.9.0 + Copyright (c) 2026 Davide Grilli + 1.0.0 true diff --git a/README.md b/README.md index 1ec6e78..203cfb6 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,13 @@ passaggio, non lo sostituisce. 1. **Indice CAD** — all'avvio carica automaticamente `cad_index.db` dalla cartella di installazione (`%LOCALAPPDATA%\Programs\PrepStep`). Se manca, lo si crea con **Aggiorna indice**, oppure si apre un altro DB per la sola sessione - con **Apri DB...**. **Aggiorna indice** che scansiona il disco (di default `X:\`, tutte le cartelle di primo - livello che trova) e indicizza tutti i file. La **cartella di lavoro** (dove - finiscono il CSV e la cartella `raw/`; gli STEP esportati con Creo vanno in - `step/`, dentro la stessa cartella) è l'ultima scelta (ricordata tra un avvio e - l'altro) o, la prima volta, la cartella di installazione, modificabile in qualunque momento da **File → Scegli - cartella di lavoro...**. + con **Apri DB...**. **Aggiorna indice** scansiona il disco (di default `X:\`, + tutte le cartelle di primo livello che trova) e indicizza tutti i file. La + **cartella di lavoro** (dove finiscono il CSV e la cartella `raw/`; gli STEP + esportati con Creo vanno in `step/`, dentro la stessa cartella) è di default la + cartella di installazione, modificabile in qualunque momento da **File → Scegli + cartella di lavoro...** (la scelta viene ricordata). Dal menu **File** si + ripuliscono anche `raw/`/`step/` e i CSV accumulati. 2. **Importa Distinta Base** — trascina (o scegli da file) l'estrazione `.xls`/`.xml` del gestionale (foglio "Distinta Base", colonne Componente/Descrizione): viene generato un CSV nella cartella di lavoro, con @@ -34,7 +35,7 @@ passaggio, non lo sostituisce. `raw/` per trovare ricorsivamente i sotto-assiemi/parti che li compongono, copiandoli a loro volta in `raw/` (passo opzionale se la distinta contiene solo parti singole). -5. **Trascina su Creo** — mostra i file `.asm` della distinta già in `raw/`, +5. **Verifica completezza** — mostra i file `.asm` della distinta già in `raw/`, trascinabili su Creo Distributed Batch per l'esportazione STEP (passo manuale, fuori da quest'app): scrive in `step/`, dentro la cartella di lavoro. @@ -88,16 +89,27 @@ installato. ## Setup di installazione -Per distribuire l'app agli utenti si genera un setup con [Inno Setup 6](https://jrsoftware.org/isinfo.php) -(una volta sola: `winget install JRSoftware.InnoSetup --scope user`). Dalla root del repo, -**dopo** il `dotnet publish` qui sopra: +Per distribuire l'app agli utenti si genera un setup con +[Inno Setup 6](https://jrsoftware.org/isinfo.php). + +Una volta sola, per installare Inno Setup (per l'utente corrente, senza admin): ```powershell +winget install --id JRSoftware.InnoSetup -e --scope user +``` + +A ogni release, dalla root del repo: + +```powershell +# 1. aggiorna in PrepStep\PrepStep.csproj e la voce in CHANGELOG.md +# 2. chiudi l'app se è aperta (l'exe in uso blocca la build) +dotnet publish PrepStep -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o PrepStep\publish & "$env:LOCALAPPDATA\Programs\Inno Setup 6\ISCC.exe" installer\PrepStep.iss ``` Produce `installer\Output\PrepStep-Setup-.exe` (versione letta dall'exe, cioè -`` del csproj). Il setup: +`` del csproj): è l'unico file da distribuire. Per provarlo sul proprio PC basta +lanciarlo (`.\installer\Output\PrepStep-Setup-.exe`). Il setup: - installa **solo per l'utente corrente**, in `%LOCALAPPDATA%\Programs\PrepStep`, senza chiedere i diritti di amministratore; @@ -112,16 +124,22 @@ senza chiedere) — es. per distribuirla da script: ## Struttura del progetto -Tutto il codice è in `PrepStep/` (unico progetto nella solution, GUI e -indicizzazione integrate): +Il codice dell'app è tutto in `PrepStep/` (GUI e indicizzazione integrate); accanto ci sono +il progetto di test `PrepStep.Tests/`, gli script standalone `scripts/` e lo script del setup +`installer/`. Mappa file-per-file completa in [`docs/architettura.md`](docs/architettura.md). - `Program.cs` — entry point. -- `Form1.cs` — finestra principale (indice CAD, import Distinta Base, griglia - risultati); UI costruita interamente in codice, nessun designer visuale. +- `Form1.cs` — finestra principale, wizard a 5 fasi e menu; UI costruita interamente in + codice (`Form1.Designer.cs` è solo lo scheletro del template). - `Indexer.cs` — scansione del disco e scrittura/aggiornamento del DB SQLite. - `DistintaBaseImporter.cs` — parsing del file Distinta Base (SpreadsheetML XML o Excel binario/OpenXML tramite ExcelDataReader) e generazione CSV. -- `ProgressForm.cs` — dialog di avanzamento durante l'aggiornamento indice. +- `AsmRecordReader.cs` — lettura esatta dei record dei `.asm` (fase 4). +- `AssemblyComponentScanner.cs` — euristica testuale di fallback per i `.asm` fuori formato. +- `ProgressForm.cs`, `ProgressoComponentiForm.cs` — avanzamento di scansione e fase 4. +- `PrtMancantiForm.cs` — esito di "Trova componenti referenziati". +- `GuidaForm.cs` — guida in-app (Aiuto → Guida, F1). +- `UiStile.cs` — stile condiviso di bottoni, card e barre. Il database generato (`cad_index.db`), i file Excel/CSV della distinta trascinati nella root e le cartelle `raw/`/`step/` sono rigenerabili e non @@ -129,12 +147,18 @@ sono tracciati in git (vedi `.gitignore`). ## Test -`PrepStep.Tests/` contiene unit test (regex di estrazione dei componenti -dai `.asm`, parsing del nome file Pro-E) e integration test (schema/vista SQL -reale, con focus sui bug di case-sensitivity/duplicati già risolti). Da +`PrepStep.Tests/` (xUnit) contiene unit test (lettore esatto e euristica di +estrazione dei componenti dai `.asm`, parsing del nome file Pro-E, import della +distinta) e integration test (scansione su disco, schema/vista SQL reale con focus +sui bug di case-sensitivity/duplicati già risolti, pipeline end-to-end). Da eseguire: ```powershell cd PrepStep.Tests dotnet test ``` + +## Licenza + +Software proprietario, © 2026 Davide Grilli, tutti i diritti riservati: vedi +[`LICENSE`](LICENSE). diff --git a/docs/architettura.md b/docs/architettura.md index b7d8f68..cceb139 100644 --- a/docs/architettura.md +++ b/docs/architettura.md @@ -35,7 +35,8 @@ successiva. **1. Indice della share → `cad_index.db`.** `Indexer.ScanAsync` cammina tutte le cartelle di primo livello sotto `X:\`, riconosce i nomi Pro-E `..` e fa un upsert incrementale (confronto su percorso+dimensione+data), così i giri successivi costano solo il -delta. Qui si sceglie anche la **cartella di lavoro**, che da qui in poi ospita tutto il resto. +delta. La **cartella di lavoro**, che da qui in poi ospita tutto il resto, non si sceglie qui +ma da "File → Scegli cartella di lavoro..." (default: cartella di installazione). **2. Distinta del gestionale → CSV.** `DistintaBaseImporter.ConvertiInCsv` riduce l'export a due colonne `componente;descrizione`. Se il nome del file segue la convenzione @@ -113,9 +114,12 @@ trascinano i `.asm` su Creo Distributed Batch, che scrive in `step/`. docs. Altre responsabilità in Form1.cs: - - `TrovaPercorsiCad` / `CaricaCodiciNoti` — query sul DB (`files_ultima_versione`), la - seconda carica tutti i codici prt/asm noti in un colpo solo (usata sia per risolvere i - componenti sia da `AssemblyComponentScanner` per validare i token generici). + - `TrovaPercorsiCad` / `CaricaCodiciNoti` — query sul DB (`files_ultima_versione`): la + prima risolve i componenti del CSV (fase 3), la seconda carica tutti i codici prt/asm noti + in un colpo solo, usata in fase 4 solo per validare i token generici di + `AssemblyComponentScanner`. + - `CaricaCandidati` — in fase 4, tutte le copie di ogni codice dalla tabella `files` (non + dalla vista), da cui `ScegliPerCartella` sceglie quella da copiare in `raw/`. - `CopiaFileTrovati` — copia (in parallelo, grado 6) i file trovati in `raw/`, saltando silenziosamente quelli irraggiungibili (share offline/permessi). - `PulisciRawEStep` — svuota `raw/` e `step/` nella cartella di lavoro (manutenzione, @@ -240,8 +244,10 @@ completi". sotto-assiemi trovati e copiati in `raw/`, più i codici referenziati che non corrispondono a nessun file indicizzato (possono essere disegni, componenti davvero mancanti, o falsi positivi della scansione `.asm`). -- **GuidaForm.cs** — guida interattiva ("Aiuto → Guida"/F1): lista delle 5 fasi a sinistra, - testo a destra; sintesi, il dettaglio resta solo in questi docs. +- **GuidaForm.cs** — guida interattiva ("Aiuto → Guida"/F1): elenco delle sezioni a sinistra + (Panoramica, Dove finiscono i file, Prima di iniziare, le 5 fasi, Ripartire da capo), testo + a destra; stessa guida di `docs/guida-utente.md`, il dettaglio tecnico resta solo in questi + docs. ## Persistenza @@ -284,11 +290,11 @@ C# file-based apps (.NET 10, `dotnet run scripts/Nome.cs -- arg1 arg2`, nessun ` dipendenze extra con `#:package Nome@versione` in testa al file): - **ExtractCreoStrings.cs** — BOM di un `.asm` risolvendo ricorsivamente i sotto-assiemi - contro `cad_index.db` (stessa logica di `AssiemeCompleto` in Form1, solo codici numerici + contro `cad_index.db` con `AssemblyComponentScanner` (via `#:project`, solo codici numerici Pro-E). - **BomViaDb.cs** — come sopra ma con la tokenizzazione generica validata contro il DB, per intercettare anche i nomi alfabetici delle parti commerciali. -- **CreoBom.cs** — usa `AsmRecordReader` (stesso lettore esatto della GUI, fase 4/5, via +- **CreoBom.cs** — usa `AsmRecordReader` (stesso lettore esatto della GUI, fase 4, via `#:project`) invece dell'euristica testuale. Risolve i sottoassiemi cercandoli in cartelle locali (`-p`), non contro `cad_index.db` come `ExtractCreoStrings.cs`/`BomViaDb.cs`. - **Analyze.cs** — dump del contesto testo/hex attorno a un pattern in un file binario, per diff --git a/docs/db-cad-index.md b/docs/db-cad-index.md index e3d32b5..ddc19ee 100644 --- a/docs/db-cad-index.md +++ b/docs/db-cad-index.md @@ -29,10 +29,12 @@ componenti e nel filtro per cartella). Vista `files_ultima_versione`: stessa struttura di `files`, filtrata alla sola riga con `versione` più alta per ogni `(cartella_radice, codice, tipo_file)`, tramite `ROW_NUMBER() -OVER (PARTITION BY ... ORDER BY versione DESC, data_modifica DESC, percorso_completo)`. Tutte -le ricerche di componenti (`Form1.TrovaPercorsiCad`, `Form1.CaricaCodiciNoti`) interrogano -questa vista, non `files` direttamente, così un componente con più versioni sulla share -risolve sempre all'ultima. Deliberatamente una `ROW_NUMBER()` invece di un self-join con +OVER (PARTITION BY ... ORDER BY versione DESC, data_modifica DESC, percorso_completo)`. Le +ricerche per codice (`Form1.TrovaPercorsiCad` in fase 3, `Form1.CaricaCodiciNoti`) +interrogano questa vista, non `files` direttamente, così un componente con più versioni sulla +share risolve sempre all'ultima. Fa eccezione la fase 4 (`Form1.CaricaCandidati`), che legge +`files` per avere tutte le copie di un codice in cartelle diverse e scegliere quella giusta +(`ScegliPerCartella`). Deliberatamente una `ROW_NUMBER()` invece di un self-join con `GROUP BY`: su ~200k righe un self-join degenera in tempi quasi quadratici, `ROW_NUMBER()` resta lineare. @@ -60,8 +62,9 @@ ciascuna — non una sola in assoluto. `TrovaPercorsiCad` gestisce questo caso d Chiamato da "Aggiorna indice" (fase 1) e riutilizza lo stesso `dbPath` già caricato. -1. Crea lo schema se non esiste (`CREATE TABLE/VIEW IF NOT EXISTS`) — quindi funziona sia su - un DB vuoto (prima esecuzione) sia su uno esistente (aggiornamento incrementale). +1. Crea lo schema se non esiste (`CREATE TABLE/INDEX IF NOT EXISTS`; la vista invece è + `DROP`+`CREATE` a ogni scan) — quindi funziona sia su un DB vuoto (prima esecuzione) sia su + uno esistente (aggiornamento incrementale). 2. Cancella subito tutte le righe con `cartella_radice LIKE 'temp\_%'`: le cartelle `temp_paris`, `temp_davide`, `temp_studi esterni`, ecc. sono lavori personali/temporanei che possono contenere copie datate con lo stesso codice numerico di file "ufficiali" altrove @@ -138,10 +141,11 @@ indicizzati) prima di sospettare un bug nella ricerca. riga con quell'esatto `codice`. In presenza di duplicati su più `cartella_radice`, tiene solo il primo per `tipo_file` (il più recente, dato l'`ORDER BY data_modifica DESC`) e scarta gli altri. -- **Risoluzione codici noti per lo scanner assiemi** (`Form1.CaricaCodiciNoti`, usata sia dalla - GUI in fase 4 sia da `scripts/BomViaDb.cs`): carica in un'unica query tutti i codici - prt/asm noti con i relativi percorsi, invece di una query per codice — usata per validare i - token generici trovati nei binari `.asm` (vedi `docs/formato-asm.md`). +- **Codici noti per lo scanner assiemi** (`Form1.CaricaCodiciNoti`, fase 4; + `scripts/BomViaDb.cs` fa una query equivalente per conto suo): carica in un'unica query tutti + i codici prt/asm noti, invece di una query per codice — usata solo per validare i token + generici trovati nei binari `.asm` (vedi `docs/formato-asm.md`). I percorsi da copiare + vengono invece da `Form1.CaricaCandidati` (tabella `files`, vedi sopra). ## Debug ad-hoc diff --git a/docs/formato-asm-record.md b/docs/formato-asm-record.md index 4af4d95..42d45b4 100644 --- a/docs/formato-asm-record.md +++ b/docs/formato-asm-record.md @@ -8,8 +8,8 @@ l'euristica testuale ("codice che compare almeno due volte") descritta in struttura effettiva dei record. Implementazione: lettura in [`PrepStep/AsmRecordReader.cs`](../PrepStep/AsmRecordReader.cs) -(condivisa con la GUI, `Form1.EstraiCodiciReferenziati` in fase "Trova componenti -referenziati"/"Verifica completezza" - con fallback su `AssemblyComponentScanner` per i file +(condivisa con la GUI, `Form1.EstraiCodiciReferenziati` in fase 4 "Trova componenti +referenziati" - con fallback su `AssemblyComponentScanner` per i file che non rispettano il formato validato), resa in formato BOM e ricorsione sui sottoassiemi in [`scripts/CreoBom.cs`](../scripts/CreoBom.cs) (via `#:project`). @@ -91,7 +91,7 @@ conteggio dei membri: con la lettura a 1 byte fisso i campioni grandi si disallineavano. Non è confermata da una specifica; regge sui campioni disponibili al momento del reverse engineering. -In `CreoBom.cs` è `AsmRecordReader.AsInt`, applicata al testo decodificato Latin1 (ogni `char` +Nel codice è `AsmRecordReader.AsInt` (privata, in `PrepStep/AsmRecordReader.cs`), applicata al testo decodificato Latin1 (ogni `char` della stringa corrisponde 1:1 a un byte, quindi indicizzare la stringa o l'array di byte originale dà lo stesso offset). diff --git a/docs/formato-asm.md b/docs/formato-asm.md index e5b1658..5a22e94 100644 --- a/docs/formato-asm.md +++ b/docs/formato-asm.md @@ -12,8 +12,8 @@ Un reverse engineering successivo ha decodificato la **struttura a record** del solo pattern testuali): legge esattamente la sezione `members` di un assieme, senza contare occorrenze né rischiare i falsi positivi descritti in questo documento. Implementato in `PrepStep/AsmRecordReader.cs`, documentato in [`formato-asm-record.md`](formato-asm-record.md). -È il metodo **preferito** in GUI (fase "Trova componenti referenziati"/"Verifica -completezza", `Form1.EstraiCodiciReferenziati`) e nello script `CreoBom.cs`: +È il metodo **preferito** in GUI (fase 4 "Trova componenti referenziati", +`Form1.EstraiCodiciReferenziati`) e nello script `CreoBom.cs`: `AssemblyComponentScanner` (l'euristica di questo documento) resta come **fallback**, usato solo quando `AsmRecordReader` lancia `InvalidDataException` (file che non rispetta il formato validato dal reverse engineering — copertura limitata agli 8 campioni disponibili al @@ -55,8 +55,9 @@ regex: \b\d{8,12}(?:_[A-Za-z]\d{2,4}|[A-Za-z]{0,2})\b occorrenze: >= 2 ``` -`scripts/ExtractCreoStrings.cs` ha una versione più raffinata della regex e un filtro -aggiuntivo (vedi sotto), non ancora portati in `AssemblyComponentScanner.cs`: +La regex effettiva in `AssemblyComponentScanner.cs` (usata anche da +`scripts/ExtractCreoStrings.cs` via `#:project`) è una versione più raffinata, con in più il +filtro sui falsi positivi descritto sotto: ``` regex: \b\d{8,12}[A-Za-z]{0,2}(?:_[A-Za-z]?\d{2,4})?\b @@ -285,8 +286,8 @@ livello) serve una BFS: Stessa logica di estrazione candidati ed euristica del codice radice (sopra), duplicata in due punti del codice per scopi diversi: -- [`AssemblyComponentScanner.EstraiCodiciReferenziati`](../PrepStep/AssemblyComponentScanner.cs) + `CodiceRadice` — estrazione dei candidati da un file, usata dalla BFS in [`Form1.RisolviAlberoComponenti`](../PrepStep/Form1.cs) (fase "Trova componenti referenziati") e [`Form1.AssiemeCompleto`](../PrepStep/Form1.cs) (fase "Verifica completezza"). Entrambe seminano l'insieme dei codici visitati con codice + radice di ogni file di partenza, e caricano una volta sola tutti i codici noti all'indice (`Form1.CaricaCodiciNoti`) sia per validare i token generici delle parti commerciali sia per risolvere i percorsi dei componenti trovati, senza una query SQL per candidato. -- [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) e [`scripts/BomViaDb.cs`](../scripts/BomViaDb.cs) — stessa BFS ricorsiva standalone da riga di comando (copia indipendente della stessa euristica, nessun `ProjectReference` verso la GUI). Usati per confrontare l'euristica contro l'albero Creo di un singolo file durante il reverse engineering, senza dover passare dalla UI/dal DB `raw`. +- [`AssemblyComponentScanner.EstraiCodiciReferenziati`](../PrepStep/AssemblyComponentScanner.cs) + `CodiceRadice` — estrazione dei candidati da un file, usata come fallback dalla BFS in [`Form1.RisolviAlberoComponenti`](../PrepStep/Form1.cs) (fase 4 "Trova componenti referenziati"). La BFS semina l'insieme dei codici visitati con codice + radice di ogni file di partenza e carica una volta sola i codici noti all'indice (`Form1.CaricaCodiciNoti`, per validare i token generici delle parti commerciali) e tutte le copie di ogni codice (`Form1.CaricaCandidati`, per scegliere il percorso da copiare), senza una query SQL per candidato. +- [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) e [`scripts/BomViaDb.cs`](../scripts/BomViaDb.cs) — stessa BFS ricorsiva standalone da riga di comando, che riusa `AssemblyComponentScanner` del progetto principale via `#:project` (nessuna copia dell'euristica). Usati per confrontare l'euristica contro l'albero Creo di un singolo file durante il reverse engineering, senza dover passare dalla UI/dal DB `raw`. Nota: le query contro `files_ultima_versione` filtrano solo per `(cartella_radice, codice, tipo_file)` - se lo stesso codice esiste in più diff --git a/docs/guida-utente.md b/docs/guida-utente.md index ce065f0..254c8ab 100644 --- a/docs/guida-utente.md +++ b/docs/guida-utente.md @@ -80,8 +80,8 @@ Premi **Avanti** quando il database è caricato. Premila per cercare ogni componente nel database — le righe della griglia si colorano di verde (trovato) o rosso (non trovato nell'indice). -**Avanti** si sblocca solo dopo aver premuto "Verifica la presenza dei file sul server", -non basta il solo import: è il modo per accorgersi subito se il database è disallineato +**Avanti** si sblocca solo dopo aver premuto **Verifica presenza**, non basta il solo +import: è il modo per accorgersi subito se il database è disallineato rispetto alla share (es. indice non aggiornato) prima di andare avanti. ## 3. Crea cartella raw @@ -107,7 +107,7 @@ direttamente la cartella `raw/` con **Apri cartella raw**. Questo passo è opzionale se la distinta contiene solo parti singole senza sotto-assiemi: in quel caso si può passare direttamente alla fase successiva. -## 5. Trascina su Creo Distributed Batch +## 5. Verifica completezza e Creo Distributed Batch L'ultima fase mostra l'elenco dei file `.asm` della distinta già presenti in `raw/`, trascinabili. Da qui il passaggio a Creo è manuale, fuori dall'app: @@ -141,9 +141,10 @@ prima di riprovare. ## Ripartire con una nuova distinta -Quando devi processare un'altra distinta, usa **File → Nuovo** (Ctrl+N): azzera CSV, raw -e verifica delle fasi 2-5 e riporta al passo 2, senza dover ricaricare il database o -la cartella di lavoro (restano quelli già impostati in fase 1). +Quando devi processare un'altra distinta, usa **File → Nuovo** (Ctrl+N): svuota le griglie e +la verifica delle fasi 2-5 e riporta al passo 2, senza dover ricaricare il database né +cambiare la cartella di lavoro. Non cancella nessun file su disco: CSV, `raw/` e `step/` +restano (vedi sotto per ripulirli). Per ripulire le cartelle `raw/` e `step/` della cartella di lavoro prima di un nuovo giro (senza toccare l'indice), usa **File → Pulisci raw e step...**. diff --git a/installer/PrepStep.iss b/installer/PrepStep.iss index a95a3eb..b9db797 100644 --- a/installer/PrepStep.iss +++ b/installer/PrepStep.iss @@ -16,6 +16,7 @@ AppId={{{#AppGuid}} AppName=PrepStep - Cevolani AppVersion={#AppVersion} AppPublisher=Cevolani +AppCopyright=Copyright (c) 2026 Davide Grilli ; Con PrivilegesRequired=lowest {autopf} diventa %LOCALAPPDATA%\Programs. PrivilegesRequired=lowest DefaultDirName={autopf}\PrepStep