Ridisegna la fase 1 in card di stato e aggiunge un passo esplicito di verifica in fase 2

Fase 1: le info su DB e cartella di lavoro erano testo grigio uniforme
disallineato con bottoni squadrati senza gerarchia. Ora vivono in una
card di stato ("Database") con un indicatore verde/rosso per lo stato
di caricamento; la card "Cartella di lavoro" è stata rimossa (resta
gestibile da File → Scegli cartella di lavoro..., già presente nel
menu). Le icone sui bottoni (prima Segoe MDL2 Assets, poi disegnate a
mano via GDI+) sono state provate e infine tolte su richiesta: restano
solo testo, più semplici da mantenere per due bottoni.

Fase 2: "Verifica presenza" ora compare solo dopo un import riuscito
(dialogo o drag&drop) invece di essere sempre visibile, ed è lei —non
il solo import— a sbloccare "Avanti" (mancava la constatazione che
l'utente può ancora avanzare senza aver verificato che i file esistano
sul server). Aggiunte etichette numerate "1. Carica la distinta" /
"2. Verifica la presenza dei file sul server" accanto ai bottoni, e
rimosso il messaggio verde ridondante dopo l'import.

Doc aggiornati nello stesso commit: CLAUDE.md, docs/architettura.md,
GuidaForm.cs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5 committed 2026-09-22 15:50:29 +02:00
1 parent 3e9c78074c
commit e94331b69f
5 files changed
+166 -73

No files matched your search

+13 -9
View File
@@ -73,16 +73,20 @@ che conta per capire il prodotto.
designer visuale): designer visuale):
1. **Database** — carica/aggiorna `cad_index.db` (`Indexer.ScanAsync`, radice disco di 1. **Database** — carica/aggiorna `cad_index.db` (`Indexer.ScanAsync`, radice disco di
default `X:\` hardcoded in `RadiceDiscoDefault`); mostra anche la **cartella di lavoro** default `X:\` hardcoded in `RadiceDiscoDefault`); un pallino verde/rosso accanto al titolo
(destinazione di CSV/`raw/`/`step/`), proposta dall'ultima usata o dalla cartella del DB se indica se un DB è caricato. La **cartella di lavoro** (destinazione di CSV/`raw/`/`step/`)
non c'è ancora nulla di salvato — cambiabile da "File → Scegli cartella di lavoro..." (non non è più mostrata qui — proposta dall'ultima usata o dalla cartella del DB se non c'è
più un bottone in fase 1: azione occasionale, non un passo del flusso) — vedi ancora nulla di salvato, cambiabile in qualunque momento da "File → Scegli cartella di
`docs/db-cad-index.md` per il dettaglio di schema e risoluzione del percorso DB. lavoro..." — vedi `docs/db-cad-index.md` per il dettaglio di schema e risoluzione del
percorso DB.
2. **Importa Distinta Base** — `DistintaBaseImporter.ConvertiInCsv` genera il CSV 2. **Importa Distinta Base** — `DistintaBaseImporter.ConvertiInCsv` genera il CSV
componente;descrizione nella cartella di lavoro; se il file segue la convenzione del componente;descrizione nella cartella di lavoro (da file scelto o trascinato); se il file
gestionale (`DBP_<codice>_<timestamp>`), aggiunge l'assieme generale come riga in più (da segue la convenzione del gestionale (`DBP_<codice>_<timestamp>`), aggiunge l'assieme
quel momento è un componente come tutti gli altri, nessun caso speciale nel resto del generale come riga in più (da quel momento è un componente come tutti gli altri, nessun
codice). caso speciale nel resto del codice). Il bottone "Verifica presenza" compare solo dopo un
import riuscito e cerca i componenti nell'indice (`VerificaCodiciNelDb`, righe colorate in
verde/rosso in griglia): è quello — non il solo import — a sbloccare "Avanti"
(`AvantiConsentito`).
3. **Crea cartella raw** — `TrovaPercorsiCad` + `CopiaFileTrovati` (parallela, vedi 3. **Crea cartella raw** — `TrovaPercorsiCad` + `CopiaFileTrovati` (parallela, vedi
`docs/copia-raw-parallela.md`) copiano in `raw/` i file CAD dei componenti del CSV trovati `docs/copia-raw-parallela.md`) copiano in `raw/` i file CAD dei componenti del CSV trovati
nell'indice. nell'indice.
+100 -45
View File
@@ -1,4 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.Drawing.Drawing2D;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
namespace PrepStep; namespace PrepStep;
@@ -10,11 +11,13 @@ public partial class Form1 : Form
private readonly Button _btnCreaRaw = new(); private readonly Button _btnCreaRaw = new();
private readonly Button _btnTrovaPrt = new(); private readonly Button _btnTrovaPrt = new();
private readonly Button _btnVerifica = new(); private readonly Button _btnVerifica = new();
private readonly FlowLayoutPanel _rigaVerifica = new();
private readonly ListView _lstAnteprimaAsm = new(); private readonly ListView _lstAnteprimaAsm = new();
private readonly Label _lblStatus = new(); private readonly Label _lblStatus = new();
private readonly Label _lblDb = new(); private readonly Label _lblDb = new();
private readonly Label _lblUltimoAggiornamento = new(); private readonly Label _lblUltimoAggiornamento = new();
private readonly Label _lblCartellaLavoro = new(); private readonly Panel _indicatoreDb = new();
private bool _dbCaricato;
private readonly DataGridView _gridImport = new(); private readonly DataGridView _gridImport = new();
private readonly DataGridView _gridRaw = new(); private readonly DataGridView _gridRaw = new();
private readonly Label _lblImportStatus = new(); private readonly Label _lblImportStatus = new();
@@ -250,7 +253,7 @@ public partial class Form1 : Form
private bool AvantiConsentito(int fase) => fase switch private bool AvantiConsentito(int fase) => fase switch
{ {
0 => _dbPath is not null && _cartellaLavoro is not null, 0 => _dbPath is not null && _cartellaLavoro is not null,
1 => _righeCorrenti is { Count: > 0 }, 1 => _righeCorrenti is { Count: > 0 } && _ultimaVerifica is not null,
2 => _ultimaCartellaRaw is not null, 2 => _ultimaCartellaRaw is not null,
3 => true, // risoluzione ricorsiva opzionale: non tutti gli assiemi hanno sotto-componenti 3 => true, // risoluzione ricorsiva opzionale: non tutti gli assiemi hanno sotto-componenti
_ => true, _ => true,
@@ -278,6 +281,7 @@ public partial class Form1 : Form
_gridRaw.Rows.Clear(); _gridRaw.Rows.Clear();
_lstAnteprimaAsm.Items.Clear(); _lstAnteprimaAsm.Items.Clear();
ImpostaStatoImport("", Color.Black); ImpostaStatoImport("", Color.Black);
_rigaVerifica.Visible = false;
VaiAllaFase(1); VaiAllaFase(1);
} }
@@ -301,57 +305,78 @@ public partial class Form1 : Form
Dock = DockStyle.Top, Dock = DockStyle.Top,
AutoSize = true, AutoSize = true,
ForeColor = SystemColors.GrayText, ForeColor = SystemColors.GrayText,
Margin = new Padding(0, 0, 0, 12), Margin = new Padding(0, 0, 0, 16),
Text = "L'indice CAD viene caricato automaticamente all'avvio, se già presente. " Text = "L'indice CAD viene caricato automaticamente all'avvio, se già presente.",
+ "Usa 'Apri DB...' per selezionarne un altro, oppure 'Aggiorna indice' per "
+ "scansionare di nuovo il disco (X:\\).",
}; };
contenuto.Controls.Add(lblIstruzioni); contenuto.Controls.Add(lblIstruzioni);
var cardDb = UiStile.Card();
var contenutoCardDb = new TableLayoutPanel
{
Dock = DockStyle.Top,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
ColumnCount = 1,
};
contenutoCardDb.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
var rigaTitoloDb = new FlowLayoutPanel
{
AutoSize = true,
FlowDirection = FlowDirection.LeftToRight,
Margin = new Padding(0, 0, 0, 6),
};
_indicatoreDb.Size = new Size(10, 10);
_indicatoreDb.Margin = new Padding(0, 5, 8, 0);
_indicatoreDb.Paint += (_, e) =>
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
var colore = _dbCaricato ? Color.FromArgb(30, 160, 90) : Color.FromArgb(200, 60, 60);
using var pennello = new SolidBrush(colore);
e.Graphics.FillEllipse(pennello, 0, 0, _indicatoreDb.Width - 1, _indicatoreDb.Height - 1);
};
rigaTitoloDb.Controls.Add(_indicatoreDb);
var lblTitoloDb = new Label
{
AutoSize = true,
Font = new Font(Font, FontStyle.Bold),
Text = "Database",
};
rigaTitoloDb.Controls.Add(lblTitoloDb);
contenutoCardDb.Controls.Add(rigaTitoloDb);
_lblDb.Dock = DockStyle.Top; _lblDb.Dock = DockStyle.Top;
_lblDb.AutoSize = true; _lblDb.AutoSize = true;
_lblDb.ForeColor = SystemColors.GrayText; _lblDb.ForeColor = SystemColors.ControlText;
_lblDb.Margin = new Padding(0, 0, 0, 4); _lblDb.Margin = new Padding(0, 0, 0, 2);
contenuto.Controls.Add(_lblDb); contenutoCardDb.Controls.Add(_lblDb);
_lblUltimoAggiornamento.AutoSize = true; _lblUltimoAggiornamento.AutoSize = true;
_lblUltimoAggiornamento.ForeColor = SystemColors.GrayText; _lblUltimoAggiornamento.ForeColor = SystemColors.GrayText;
_lblUltimoAggiornamento.Margin = new Padding(0, 0, 0, 12); _lblUltimoAggiornamento.Margin = new Padding(0, 0, 0, 14);
contenuto.Controls.Add(_lblUltimoAggiornamento); contenutoCardDb.Controls.Add(_lblUltimoAggiornamento);
var bottoni = new FlowLayoutPanel { AutoSize = true, FlowDirection = FlowDirection.LeftToRight }; var bottoniDb = new FlowLayoutPanel { AutoSize = true, FlowDirection = FlowDirection.LeftToRight };
_btnApriDb.Text = "Apri DB..."; _btnApriDb.Text = "Apri DB...";
_btnApriDb.Margin = new Padding(0, 0, 8, 0); _btnApriDb.Margin = new Padding(0, 0, 8, 0);
UiStile.Secondario(_btnApriDb); UiStile.Secondario(_btnApriDb);
UiStile.Arrotonda(_btnApriDb);
_btnApriDb.Click += (_, _) => ScegliDatabase(); _btnApriDb.Click += (_, _) => ScegliDatabase();
bottoni.Controls.Add(_btnApriDb); bottoniDb.Controls.Add(_btnApriDb);
_btnAggiorna.Text = "Aggiorna indice"; _btnAggiorna.Text = "Aggiorna indice";
UiStile.Secondario(_btnAggiorna); UiStile.Secondario(_btnAggiorna);
UiStile.Arrotonda(_btnAggiorna);
_btnAggiorna.Click += (_, _) => AggiornaIndice(); _btnAggiorna.Click += (_, _) => AggiornaIndice();
bottoni.Controls.Add(_btnAggiorna); bottoniDb.Controls.Add(_btnAggiorna);
contenuto.Controls.Add(bottoni); contenutoCardDb.Controls.Add(bottoniDb);
cardDb.Controls.Add(contenutoCardDb);
var lblIstruzioniCartella = new Label contenuto.Controls.Add(cardDb);
{
Dock = DockStyle.Top,
AutoSize = true,
ForeColor = SystemColors.GrayText,
Margin = new Padding(0, 20, 0, 4),
Text = "Cartella di lavoro: qui vengono scritti il CSV della distinta e la "
+ "cartella 'raw' (gli STEP esportati con Creo vanno invece in 'step', "
+ "dentro la stessa cartella). Proposta automaticamente (ricordata da un "
+ "avvio all'altro), modificabile da 'File → Scegli cartella di lavoro...'.",
};
contenuto.Controls.Add(lblIstruzioniCartella);
_lblCartellaLavoro.Dock = DockStyle.Top;
_lblCartellaLavoro.AutoSize = true;
_lblCartellaLavoro.ForeColor = SystemColors.GrayText;
_lblCartellaLavoro.Margin = new Padding(0, 0, 0, 4);
contenuto.Controls.Add(_lblCartellaLavoro);
var panel = new Panel(); var panel = new Panel();
panel.Controls.Add(contenuto); panel.Controls.Add(contenuto);
@@ -382,20 +407,47 @@ public partial class Form1 : Form
}; };
contenuto.Controls.Add(lblIstruzioni); contenuto.Controls.Add(lblIstruzioni);
var rigaImporta = new FlowLayoutPanel
{
AutoSize = true,
FlowDirection = FlowDirection.LeftToRight,
Margin = new Padding(0, 0, 0, 8),
};
var btnSfoglia = new Button var btnSfoglia = new Button
{ {
Text = "Scegli file distinta...", Text = "Scegli file distinta...",
Margin = new Padding(0, 0, 0, 8), Margin = new Padding(0, 0, 8, 0),
}; };
UiStile.Secondario(btnSfoglia); UiStile.Secondario(btnSfoglia);
btnSfoglia.Click += (_, _) => ScegliFileDistinta(); btnSfoglia.Click += (_, _) => ScegliFileDistinta();
contenuto.Controls.Add(btnSfoglia); rigaImporta.Controls.Add(btnSfoglia);
rigaImporta.Controls.Add(new Label
{
AutoSize = true,
ForeColor = SystemColors.GrayText,
Margin = new Padding(0, 9, 0, 0),
Text = "1. Carica la distinta",
});
contenuto.Controls.Add(rigaImporta);
_rigaVerifica.AutoSize = true;
_rigaVerifica.FlowDirection = FlowDirection.LeftToRight;
_rigaVerifica.Margin = new Padding(0, 0, 0, 8);
_rigaVerifica.Visible = false; // compare solo dopo un import riuscito (file o drag&drop)
_btnVerifica.Text = "Verifica presenza"; _btnVerifica.Text = "Verifica presenza";
_btnVerifica.Margin = new Padding(0, 0, 0, 8); _btnVerifica.Margin = new Padding(0, 0, 8, 0);
UiStile.Secondario(_btnVerifica); UiStile.Secondario(_btnVerifica);
_btnVerifica.Click += (_, _) => VerificaCodiciNelDb(); _btnVerifica.Click += (_, _) => VerificaCodiciNelDb();
contenuto.Controls.Add(_btnVerifica); _rigaVerifica.Controls.Add(_btnVerifica);
_rigaVerifica.Controls.Add(new Label
{
AutoSize = true,
ForeColor = SystemColors.GrayText,
Margin = new Padding(0, 9, 0, 0),
Text = "2. Verifica la presenza dei file sul server",
});
contenuto.Controls.Add(_rigaVerifica);
_lblImportStatus.Dock = DockStyle.Top; _lblImportStatus.Dock = DockStyle.Top;
_lblImportStatus.AutoSize = false; _lblImportStatus.AutoSize = false;
@@ -601,7 +653,7 @@ public partial class Form1 : Form
{ {
try try
{ {
var (csv, righe) = DistintaBaseImporter.ConvertiInCsv(percorso, _cartellaLavoro!); var (_, righe) = DistintaBaseImporter.ConvertiInCsv(percorso, _cartellaLavoro!);
_percorsoInputCorrente = percorso; _percorsoInputCorrente = percorso;
_righeCorrenti = righe; _righeCorrenti = righe;
@@ -614,7 +666,8 @@ public partial class Form1 : Form
_ultimaCartellaRaw = null; _ultimaCartellaRaw = null;
_ultimaVerifica = null; _ultimaVerifica = null;
ImpostaStatoImport($"CSV generato ({righe.Count} righe): {csv}", Color.DarkGreen); ImpostaStatoImport("", Color.Black);
_rigaVerifica.Visible = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -622,6 +675,7 @@ public partial class Form1 : Form
_righeCorrenti = null; _righeCorrenti = null;
_gridImport.Rows.Clear(); _gridImport.Rows.Clear();
ImpostaStatoImport($"Errore durante la conversione: {ex.Message}", Color.DarkRed); ImpostaStatoImport($"Errore durante la conversione: {ex.Message}", Color.DarkRed);
_rigaVerifica.Visible = false;
} }
AggiornaStatoAvanti(); AggiornaStatoAvanti();
} }
@@ -649,6 +703,7 @@ public partial class Form1 : Form
? Color.FromArgb(198, 239, 206) ? Color.FromArgb(198, 239, 206)
: Color.FromArgb(255, 199, 206); : Color.FromArgb(255, 199, 206);
} }
AggiornaStatoAvanti();
} }
private void CreaCartellaRaw() private void CreaCartellaRaw()
@@ -1091,14 +1146,13 @@ public partial class Form1 : Form
/// c'è ancora una preferenza salvata (o punta a una cartella cancellata), la cartella dove si /// c'è ancora una preferenza salvata (o punta a una cartella cancellata), la cartella dove si
/// trova il DB (più sensata dell'eseguibile: quella è dove l'utente tiene il proprio lavoro, /// trova il DB (più sensata dell'eseguibile: quella è dove l'utente tiene il proprio lavoro,
/// non dov'è installata la app). Richiede quindi che InizializzaDatabase sia già stata /// non dov'è installata la app). Richiede quindi che InizializzaDatabase sia già stata
/// chiamata. Sempre modificabile con "Cambia cartella..." in fase 1.</summary> /// chiamata. Sempre modificabile con "File → Scegli cartella di lavoro...".</summary>
private void InizializzaCartellaLavoro() private void InizializzaCartellaLavoro()
{ {
var ultima = LeggiUltimaCartellaLavoro(); var ultima = LeggiUltimaCartellaLavoro();
_cartellaLavoro = ultima is not null && Directory.Exists(ultima) _cartellaLavoro = ultima is not null && Directory.Exists(ultima)
? ultima ? ultima
: (_dbPath is not null ? Path.GetDirectoryName(_dbPath) : null) ?? AppContext.BaseDirectory; : (_dbPath is not null ? Path.GetDirectoryName(_dbPath) : null) ?? AppContext.BaseDirectory;
AggiornaLabelCartellaLavoro();
AggiornaStatoAvanti(); AggiornaStatoAvanti();
} }
@@ -1114,13 +1168,10 @@ public partial class Form1 : Form
string percorso = dialog.SelectedPath; string percorso = dialog.SelectedPath;
_cartellaLavoro = percorso; _cartellaLavoro = percorso;
AggiornaLabelCartellaLavoro();
SalvaUltimaCartellaLavoro(percorso); SalvaUltimaCartellaLavoro(percorso);
AggiornaStatoAvanti(); AggiornaStatoAvanti();
} }
private void AggiornaLabelCartellaLavoro() => _lblCartellaLavoro.Text = $"Cartella di lavoro: {_cartellaLavoro}";
private static string? LeggiUltimaCartellaLavoro() private static string? LeggiUltimaCartellaLavoro()
{ {
try try
@@ -1161,6 +1212,8 @@ public partial class Form1 : Form
_lblStatus.Text = "Database non trovato. Usa 'Apri DB...' per selezionarlo oppure 'Aggiorna indice' per crearlo."; _lblStatus.Text = "Database non trovato. Usa 'Apri DB...' per selezionarlo oppure 'Aggiorna indice' per crearlo.";
_lblDb.Text = "Nessun database caricato. Premi 'Aggiorna indice' per crearlo da X:\\, oppure 'Apri DB...' se ne hai gi\u00e0 uno."; _lblDb.Text = "Nessun database caricato. Premi 'Aggiorna indice' per crearlo da X:\\, oppure 'Apri DB...' se ne hai gi\u00e0 uno.";
_lblUltimoAggiornamento.Text = ""; _lblUltimoAggiornamento.Text = "";
_dbCaricato = false;
_indicatoreDb.Invalidate();
AggiornaStatoAvanti(); AggiornaStatoAvanti();
return; return;
} }
@@ -1205,6 +1258,8 @@ public partial class Form1 : Form
MessageBox.Show(this, $"Impossibile aprire il database:\n{ex.Message}", "Errore", MessageBox.Show(this, $"Impossibile aprire il database:\n{ex.Message}", "Errore",
MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
_dbCaricato = _dbPath is not null;
_indicatoreDb.Invalidate();
AggiornaStatoAvanti(); AggiornaStatoAvanti();
} }
+9 -6
View File
@@ -17,14 +17,17 @@ public class GuidaForm : Form
"""), """),
("1. Database", """ ("1. Database", """
Carica o aggiorna l'indice "cad_index.db" a partire dalle cartelle di primo Carica o aggiorna l'indice "cad_index.db" a partire dalle cartelle di primo
livello del disco/share (radice di default X:\). Mostra anche la cartella di livello del disco/share (radice di default X:\). Un pallino verde/rosso indica
lavoro corrente, dove finiscono CSV, "raw" e "step" (cambiabile da se un database è caricato. La cartella di lavoro, dove finiscono CSV, "raw" e
"File ▸ Scegli cartella di lavoro..."). "step", si cambia da "File ▸ Scegli cartella di lavoro...".
"""), """),
("2. Importa Distinta Base", """ ("2. Importa Distinta Base", """
Converte il file della distinta (trascinabile nella finestra) in un CSV Converte il file della distinta (trascinabile nella finestra, o scelto col
componente;descrizione nella cartella di lavoro. Se il file segue la bottone "1. Carica la distinta") in un CSV componente;descrizione nella cartella
convenzione del gestionale, aggiunge anche l'assieme generale come riga. di lavoro. Se il file segue la convenzione del gestionale, aggiunge anche
l'assieme generale come riga. Poi "2. Verifica la presenza dei file sul server"
cerca i componenti nell'indice: è questo passo, non il solo import, a sbloccare
"Avanti".
"""), """),
("3. Crea cartella raw", """ ("3. Crea cartella raw", """
Cerca nell'indice i file CAD dei componenti del CSV e li copia nella Cerca nell'indice i file CAD dei componenti del CSV e li copia nella
+42 -11
View File
@@ -12,6 +12,12 @@ internal static class UiStile
/// l'RGB.</summary> /// l'RGB.</summary>
public static readonly Color ColorePrimario = Color.FromArgb(0, 99, 177); public static readonly Color ColorePrimario = Color.FromArgb(0, 99, 177);
/// <summary>Sfondo/bordo delle card di stato (es. riepilogo Database/cartella di lavoro in
/// fase 1): un grigio-azzurro appena percettibile rispetto al bianco del resto della
/// pagina, sufficiente a separare "stato attuale" da "istruzioni" senza ombre/gradienti.</summary>
public static readonly Color ColoreSfondoCard = Color.FromArgb(247, 249, 251);
public static readonly Color ColoreBordoCard = Color.FromArgb(226, 231, 236);
// AutoSize+Padding invece di una Size fissa in pixel: il bottone si dimensiona sempre // AutoSize+Padding invece di una Size fissa in pixel: il bottone si dimensiona sempre
// al proprio testo (a qualunque lunghezza/font), niente più testo che va a capo e viene // al proprio testo (a qualunque lunghezza/font), niente più testo che va a capo e viene
// tagliato in verticale quando non ci sta nella larghezza indovinata a mano. // tagliato in verticale quando non ci sta nella larghezza indovinata a mano.
@@ -48,22 +54,23 @@ internal static class UiStile
b.Cursor = Cursors.Hand; b.Cursor = Cursors.Hand;
} }
/// <summary>Arrotonda gli angoli del bottone. Si aggancia a SizeChanged invece di calcolare /// <summary>Arrotonda gli angoli del controllo (bottone o card). Si aggancia a SizeChanged
/// la Region una volta sola: con AutoSize la dimensione finale si conosce solo a layout /// invece di calcolare la Region una volta sola: con AutoSize la dimensione finale si
/// avvenuto (dopo Text/Padding), non subito dopo la creazione del controllo.</summary> /// conosce solo a layout avvenuto (dopo Text/Padding), non subito dopo la creazione del
public static void Arrotonda(Button b, int raggio = 6) /// controllo.</summary>
public static void Arrotonda(Control c, int raggio = 6)
{ {
b.SizeChanged += (_, _) => AggiornaRegione(b, raggio); c.SizeChanged += (_, _) => AggiornaRegione(c, raggio);
AggiornaRegione(b, raggio); AggiornaRegione(c, raggio);
} }
private static void AggiornaRegione(Button b, int raggio) private static void AggiornaRegione(Control c, int raggio)
{ {
if (b.Width <= 0 || b.Height <= 0) if (c.Width <= 0 || c.Height <= 0)
return; return;
int d = raggio * 2; int d = raggio * 2;
var rect = new Rectangle(Point.Empty, b.Size); var rect = new Rectangle(Point.Empty, c.Size);
using var percorso = new GraphicsPath(); using var percorso = new GraphicsPath();
percorso.AddArc(rect.X, rect.Y, d, d, 180, 90); percorso.AddArc(rect.X, rect.Y, d, d, 180, 90);
percorso.AddArc(rect.Right - d, rect.Y, d, d, 270, 90); percorso.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
@@ -71,7 +78,31 @@ internal static class UiStile
percorso.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90); percorso.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
percorso.CloseFigure(); percorso.CloseFigure();
b.Region?.Dispose(); c.Region?.Dispose();
b.Region = new Region(percorso); c.Region = new Region(percorso);
} }
/// <summary>Card di stato: sfondo/bordo leggermente distinti dalla pagina, angoli arrotondati,
/// padding interno. Il bordo va disegnato a mano (Paint) perché Region ritaglia il
/// controllo ma non lascia spazio a un Border WinForms nativo sugli angoli arrotondati.</summary>
public static Panel Card()
{
var card = new Panel
{
Dock = DockStyle.Top,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
BackColor = ColoreSfondoCard,
Padding = new Padding(18, 16, 18, 16),
Margin = new Padding(0, 0, 0, 16),
};
card.Paint += (_, e) =>
{
using var penna = new Pen(ColoreBordoCard);
e.Graphics.DrawRectangle(penna, 0, 0, card.Width - 1, card.Height - 1);
};
Arrotonda(card, 8);
return card;
}
} }
+2 -2
View File
@@ -92,8 +92,8 @@ trascinano i `.asm` su Creo Distributed Batch, che scrive in `step/`.
| # | Fase | Bottone → metodo | Cosa fa | | # | Fase | Bottone → metodo | Cosa fa |
|---|---|---|---| |---|---|---|---|
| 1 | Database | "Aggiorna indice" → `Indexer.ScanAsync` | Crea/aggiorna `cad_index.db` scansionando la share; mostra anche la cartella di lavoro corrente (cambiabile da "File → Scegli cartella di lavoro...") | | 1 | Database | "Aggiorna indice" → `Indexer.ScanAsync` | Crea/aggiorna `cad_index.db` scansionando la share; un pallino verde/rosso accanto al titolo indica se un DB è caricato. La cartella di lavoro non è mostrata qui (cambiabile in qualunque momento da "File → Scegli cartella di lavoro...") |
| 2 | Importa Distinta Base | selezione file → `ImportaDistinta` → `DistintaBaseImporter.ConvertiInCsv` | Xls/Xml gestionale → CSV componente;descrizione, scritto nella cartella di lavoro | | 2 | Importa Distinta Base | selezione file/drag&drop → `ImportaDistinta` → `DistintaBaseImporter.ConvertiInCsv`, poi "Verifica presenza" → `VerificaCodiciNelDb` | Xls/Xml gestionale → CSV componente;descrizione, scritto nella cartella di lavoro; "Verifica presenza" (visibile solo dopo un import riuscito) cerca i componenti nell'indice e colora le righe della griglia — è quella che sblocca "Avanti", non il solo import |
| 3 | Crea cartella raw | "Crea cartella raw" → `CreaCartellaRaw` | `TrovaPercorsiCad` + `CopiaFileTrovati` (parallela) → `raw/` dentro la cartella di lavoro | | 3 | Crea cartella raw | "Crea cartella raw" → `CreaCartellaRaw` | `TrovaPercorsiCad` + `CopiaFileTrovati` (parallela) → `raw/` dentro la cartella di lavoro |
| 4 | Trova componenti referenziati | "Trova componenti referenziati" → `TrovaPrtReferenziati` → `RisolviAlberoComponenti` | Legge i `.asm` in `raw/`, risolve ricorsivamente sotto-assiemi/parti nell'indice e li copia anch'essi in `raw/`, insieme ai componenti soppressi e ai modelli citati per riferimento esterno che servono a Creo per aprire l'assieme | | 4 | Trova componenti referenziati | "Trova componenti referenziati" → `TrovaPrtReferenziati` → `RisolviAlberoComponenti` | Legge i `.asm` in `raw/`, risolve ricorsivamente sotto-assiemi/parti nell'indice e li copia anch'essi in `raw/`, insieme ai componenti soppressi e ai modelli citati per riferimento esterno che servono a Creo per aprire l'assieme |
| 5 | Verifica completezza | (ingresso in fase) → `AggiornaAnteprimaAsm` | Mostra le icone trascinabili dei `.asm` della distinta già in `raw/`, da trascinare su Creo per l'esportazione STEP (Distributed Batch) | | 5 | Verifica completezza | (ingresso in fase) → `AggiornaAnteprimaAsm` | Mostra le icone trascinabili dei `.asm` della distinta già in `raw/`, da trascinare su Creo per l'esportazione STEP (Distributed Batch) |