Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff4e7a71e0 | ||
|
|
be4989fc8d | ||
|
|
e94331b69f | ||
|
|
3e9c78074c |
No files matched your search
@@ -73,15 +73,20 @@ che conta per capire il prodotto.
|
||||
designer visuale):
|
||||
|
||||
1. **Database** — carica/aggiorna `cad_index.db` (`Indexer.ScanAsync`, radice disco di
|
||||
default `X:\` hardcoded in `RadiceDiscoDefault`); qui vive anche la **cartella di lavoro**
|
||||
(destinazione di CSV/`raw/`/`step/`), proposta dall'ultima usata o dalla cartella del DB se
|
||||
non c'è ancora nulla di salvato — vedi `docs/db-cad-index.md` per il dettaglio di schema e
|
||||
risoluzione del percorso DB.
|
||||
default `X:\` hardcoded in `RadiceDiscoDefault`); un pallino verde/rosso accanto al titolo
|
||||
indica se un DB è caricato. La **cartella di lavoro** (destinazione di CSV/`raw/`/`step/`)
|
||||
non è più mostrata qui — proposta dall'ultima usata o dalla cartella del DB se non c'è
|
||||
ancora nulla di salvato, cambiabile in qualunque momento da "File → Scegli cartella di
|
||||
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
|
||||
componente;descrizione nella cartella di lavoro; se il file segue la convenzione del
|
||||
gestionale (`DBP_<codice>_<timestamp>`), aggiunge l'assieme generale come riga in più (da
|
||||
quel momento è un componente come tutti gli altri, nessun caso speciale nel resto del
|
||||
codice).
|
||||
componente;descrizione nella cartella di lavoro (da file scelto o trascinato); se il file
|
||||
segue la convenzione del gestionale (`DBP_<codice>_<timestamp>`), aggiunge l'assieme
|
||||
generale come riga in più (da quel momento è un componente come tutti gli altri, nessun
|
||||
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
|
||||
`docs/copia-raw-parallela.md`) copiano in `raw/` i file CAD dei componenti del CSV trovati
|
||||
nell'indice.
|
||||
@@ -103,9 +108,12 @@ designer visuale):
|
||||
5. **Verifica completezza** — mostra i `.asm` della distinta già in `raw/`, trascinabili su
|
||||
Creo per l'esportazione STEP (Distributed Batch, manuale, fuori dall'app).
|
||||
|
||||
Menu in cima alla finestra: "File → Nuova estrazione" (Ctrl+N) azzera lo stato delle fasi 2-5
|
||||
per ripartire con una nuova distinta, senza toccare DB/cartella di lavoro della fase 1;
|
||||
"Aiuto → Guida" (F1) apre una sintesi interattiva delle 5 fasi (`GuidaForm.cs`).
|
||||
Menu in cima alla finestra: "File → Nuovo" (Ctrl+N) azzera lo stato delle fasi 2-5
|
||||
per ripartire con una nuova distinta, senza toccare DB/cartella di lavoro della fase 1 (va
|
||||
volutamente alla fase 2, non alla 1: quei dati restano quelli già caricati); "File → Scegli
|
||||
cartella di lavoro..." cambia la cartella di CSV/`raw/`/`step/` in qualunque momento; "File →
|
||||
Pulisci raw e step..." svuota le cartelle `raw/`/`step/` nella cartella di lavoro (non tocca
|
||||
l'indice); "Aiuto → Guida" (F1) apre una sintesi interattiva delle 5 fasi (`GuidaForm.cs`).
|
||||
|
||||
## Script standalone (`scripts/`)
|
||||
|
||||
|
||||
+143
-109
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Drawing2D;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace PrepStep;
|
||||
@@ -10,19 +11,21 @@ public partial class Form1 : Form
|
||||
private readonly Button _btnCreaRaw = new();
|
||||
private readonly Button _btnTrovaPrt = new();
|
||||
private readonly Button _btnVerifica = new();
|
||||
private readonly FlowLayoutPanel _rigaVerifica = new();
|
||||
private readonly ListView _lstAnteprimaAsm = new();
|
||||
private readonly Button _btnPulisci = new();
|
||||
private readonly Label _lblStatus = new();
|
||||
private readonly Label _lblDb = new();
|
||||
private readonly Label _lblUltimoAggiornamento = new();
|
||||
private readonly Label _lblCartellaLavoro = new();
|
||||
private readonly Button _btnCambiaCartella = new();
|
||||
private readonly Panel _indicatoreDb = new();
|
||||
private bool _dbCaricato;
|
||||
private readonly DataGridView _gridImport = new();
|
||||
private readonly DataGridView _gridRaw = new();
|
||||
private readonly Label _lblImportStatus = new();
|
||||
private readonly ToolTip _tipImportStatus = new();
|
||||
private readonly MenuStrip _menu = new();
|
||||
private readonly ToolStripMenuItem _mnuNuovaEstrazione = new("Nuova estrazione");
|
||||
private readonly ToolStripMenuItem _mnuNuovaEstrazione = new("Nuovo");
|
||||
private readonly ToolStripMenuItem _mnuPulisci = new("Pulisci raw e step...");
|
||||
private readonly ToolStripMenuItem _mnuCambiaCartella = new("Scegli cartella di lavoro...");
|
||||
|
||||
// Wizard: una fase alla volta occupa tutta la finestra, si avanza solo quando quella
|
||||
// corrente è "pronta" (vedi AvantiConsentito). NomiFasi/_panelFasi sono paralleli per indice.
|
||||
@@ -92,38 +95,27 @@ public partial class Form1 : Form
|
||||
_lblFase.Font = new Font(Font, FontStyle.Bold);
|
||||
headerPanel.Controls.Add(_lblFase);
|
||||
|
||||
// Barra di navigazione come footer separato dal contenuto: linea sottile in cima e
|
||||
// sfondo bianco, invece dei bottoni appoggiati direttamente sul contenuto/sulla barra
|
||||
// di stato senza alcuna divisione visiva.
|
||||
// Padding destro = 16, lo stesso usato dai pannelli di ogni fase (Padding(16)): prima
|
||||
// era 12, quindi "Avanti" sporgeva 4px oltre il margine destro del contenuto sopra.
|
||||
var navContainer = new Panel { Dock = DockStyle.Bottom, Height = 64, BackColor = Color.White };
|
||||
var navSeparatore = new Panel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
Height = 1,
|
||||
BackColor = Color.FromArgb(220, 220, 220),
|
||||
};
|
||||
var navPanel = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.RightToLeft,
|
||||
Padding = new Padding(16, 14, 16, 14),
|
||||
};
|
||||
// Floatbar di navigazione: card staccata dai bordi della finestra invece di un footer
|
||||
// a tutta larghezza appoggiato direttamente sul contenuto/sulla barra di stato.
|
||||
var (navContainer, navPanel) = UiStile.FloatBar();
|
||||
_btnAvanti.Text = "Avanti ›";
|
||||
UiStile.Primario(_btnAvanti);
|
||||
UiStile.Arrotonda(_btnAvanti);
|
||||
_btnAvanti.Click += (_, _) => VaiAllaFase(_faseAttuale + 1);
|
||||
navPanel.Controls.Add(_btnAvanti);
|
||||
|
||||
_btnIndietro.Text = "‹ Indietro";
|
||||
_btnIndietro.Margin = new Padding(8, 0, 0, 0);
|
||||
UiStile.Secondario(_btnIndietro);
|
||||
UiStile.Arrotonda(_btnIndietro);
|
||||
UiStile.SecondarioPieno(_btnIndietro);
|
||||
|
||||
// Dimensioni uguali decise PRIMA di arrotondare: se si arrotonda un bottone e solo dopo
|
||||
// lo si ridimensiona, la Region calcolata sulla dimensione vecchia lascia un bordo
|
||||
// "fantasma" finché non arriva un repaint completo della finestra.
|
||||
UiStile.LarghezzaUguale(_btnAvanti, _btnIndietro);
|
||||
UiStile.Arrotonda(_btnAvanti, 10);
|
||||
UiStile.Arrotonda(_btnIndietro, 10);
|
||||
|
||||
_btnAvanti.Click += (_, _) => VaiAllaFase(_faseAttuale + 1);
|
||||
navPanel.Controls.Add(_btnAvanti);
|
||||
_btnIndietro.Click += (_, _) => VaiAllaFase(_faseAttuale - 1);
|
||||
navPanel.Controls.Add(_btnIndietro);
|
||||
navContainer.Controls.Add(navPanel);
|
||||
navContainer.Controls.Add(navSeparatore);
|
||||
|
||||
var statusPanel = new Panel { Dock = DockStyle.Bottom, Height = 28, BackColor = SystemColors.ControlLight };
|
||||
_lblStatus.Dock = DockStyle.Fill;
|
||||
@@ -152,6 +144,12 @@ public partial class Form1 : Form
|
||||
_mnuNuovaEstrazione.Click += (_, _) => NuovaEstrazione();
|
||||
mnuFile.DropDownItems.Add(_mnuNuovaEstrazione);
|
||||
|
||||
_mnuCambiaCartella.Click += (_, _) => ScegliCartellaLavoro();
|
||||
mnuFile.DropDownItems.Add(_mnuCambiaCartella);
|
||||
|
||||
_mnuPulisci.Click += (_, _) => PulisciRawEStep();
|
||||
mnuFile.DropDownItems.Add(_mnuPulisci);
|
||||
|
||||
var mnuAiuto = new ToolStripMenuItem("Aiuto");
|
||||
var mnuGuida = new ToolStripMenuItem("Guida") { ShortcutKeys = Keys.F1 };
|
||||
mnuGuida.Click += (_, _) => new GuidaForm().ShowDialog(this);
|
||||
@@ -244,7 +242,7 @@ public partial class Form1 : Form
|
||||
private bool AvantiConsentito(int fase) => fase switch
|
||||
{
|
||||
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,
|
||||
3 => true, // risoluzione ricorsiva opzionale: non tutti gli assiemi hanno sotto-componenti
|
||||
_ => true,
|
||||
@@ -259,7 +257,7 @@ public partial class Form1 : Form
|
||||
{
|
||||
if (_dbPath is null || _cartellaLavoro is null)
|
||||
{
|
||||
MessageBox.Show(this, "Carica prima il database in fase 1.", "Nuova estrazione",
|
||||
MessageBox.Show(this, "Carica prima il database in fase 1.", "Nuovo",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
@@ -272,6 +270,7 @@ public partial class Form1 : Form
|
||||
_gridRaw.Rows.Clear();
|
||||
_lstAnteprimaAsm.Items.Clear();
|
||||
ImpostaStatoImport("", Color.Black);
|
||||
_rigaVerifica.Visible = false;
|
||||
|
||||
VaiAllaFase(1);
|
||||
}
|
||||
@@ -295,78 +294,78 @@ public partial class Form1 : Form
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
ForeColor = SystemColors.GrayText,
|
||||
Margin = new Padding(0, 0, 0, 12),
|
||||
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:\\).",
|
||||
Margin = new Padding(0, 0, 0, 16),
|
||||
Text = "L'indice CAD viene caricato automaticamente all'avvio, se già presente.",
|
||||
};
|
||||
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.AutoSize = true;
|
||||
_lblDb.ForeColor = SystemColors.GrayText;
|
||||
_lblDb.Margin = new Padding(0, 0, 0, 4);
|
||||
contenuto.Controls.Add(_lblDb);
|
||||
_lblDb.ForeColor = SystemColors.ControlText;
|
||||
_lblDb.Margin = new Padding(0, 0, 0, 2);
|
||||
contenutoCardDb.Controls.Add(_lblDb);
|
||||
|
||||
_lblUltimoAggiornamento.AutoSize = true;
|
||||
_lblUltimoAggiornamento.ForeColor = SystemColors.GrayText;
|
||||
_lblUltimoAggiornamento.Margin = new Padding(0, 0, 0, 12);
|
||||
contenuto.Controls.Add(_lblUltimoAggiornamento);
|
||||
_lblUltimoAggiornamento.Margin = new Padding(0, 0, 0, 14);
|
||||
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.Margin = new Padding(0, 0, 8, 0);
|
||||
UiStile.Secondario(_btnApriDb);
|
||||
UiStile.Arrotonda(_btnApriDb);
|
||||
_btnApriDb.Click += (_, _) => ScegliDatabase();
|
||||
bottoni.Controls.Add(_btnApriDb);
|
||||
bottoniDb.Controls.Add(_btnApriDb);
|
||||
|
||||
_btnAggiorna.Text = "Aggiorna indice";
|
||||
UiStile.Secondario(_btnAggiorna);
|
||||
UiStile.Arrotonda(_btnAggiorna);
|
||||
_btnAggiorna.Click += (_, _) => AggiornaIndice();
|
||||
bottoni.Controls.Add(_btnAggiorna);
|
||||
bottoniDb.Controls.Add(_btnAggiorna);
|
||||
|
||||
contenuto.Controls.Add(bottoni);
|
||||
|
||||
var lblIstruzioniCartella = new Label
|
||||
{
|
||||
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 con 'Cambia cartella...'.",
|
||||
};
|
||||
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);
|
||||
|
||||
_btnCambiaCartella.Text = "Cambia cartella...";
|
||||
UiStile.Secondario(_btnCambiaCartella);
|
||||
_btnCambiaCartella.Click += (_, _) => ScegliCartellaLavoro();
|
||||
contenuto.Controls.Add(_btnCambiaCartella);
|
||||
|
||||
var lblManutenzione = new Label
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
ForeColor = SystemColors.GrayText,
|
||||
Margin = new Padding(0, 20, 0, 8),
|
||||
Text = "Manutenzione: svuota le cartelle 'raw' e 'step' nella cartella di lavoro "
|
||||
+ "prima di un nuovo giro (non tocca l'indice, solo le copie locali).",
|
||||
};
|
||||
contenuto.Controls.Add(lblManutenzione);
|
||||
|
||||
_btnPulisci.Text = "Pulisci raw e step";
|
||||
UiStile.Secondario(_btnPulisci);
|
||||
_btnPulisci.Click += (_, _) => PulisciRawEStep();
|
||||
contenuto.Controls.Add(_btnPulisci);
|
||||
contenutoCardDb.Controls.Add(bottoniDb);
|
||||
cardDb.Controls.Add(contenutoCardDb);
|
||||
contenuto.Controls.Add(cardDb);
|
||||
|
||||
var panel = new Panel();
|
||||
panel.Controls.Add(contenuto);
|
||||
@@ -397,20 +396,47 @@ public partial class Form1 : Form
|
||||
};
|
||||
contenuto.Controls.Add(lblIstruzioni);
|
||||
|
||||
var rigaImporta = new FlowLayoutPanel
|
||||
{
|
||||
AutoSize = true,
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
Margin = new Padding(0, 0, 0, 8),
|
||||
};
|
||||
var btnSfoglia = new Button
|
||||
{
|
||||
Text = "Scegli file distinta...",
|
||||
Margin = new Padding(0, 0, 0, 8),
|
||||
Margin = new Padding(0, 0, 8, 0),
|
||||
};
|
||||
UiStile.Secondario(btnSfoglia);
|
||||
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.Margin = new Padding(0, 0, 0, 8);
|
||||
_btnVerifica.Margin = new Padding(0, 0, 8, 0);
|
||||
UiStile.Secondario(_btnVerifica);
|
||||
_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.AutoSize = false;
|
||||
@@ -460,22 +486,25 @@ public partial class Form1 : Form
|
||||
};
|
||||
contenuto.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
|
||||
|
||||
var lblIstruzioni = new Label
|
||||
var rigaCreaRaw = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Top,
|
||||
AutoSize = true,
|
||||
ForeColor = SystemColors.GrayText,
|
||||
Margin = new Padding(0, 0, 0, 8),
|
||||
Text = "Cerca nell'indice il percorso CAD di ogni componente importato e copia i "
|
||||
+ "file trovati in una cartella 'raw' dentro la cartella di lavoro (fase 1).",
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
Margin = new Padding(0, 0, 0, 12),
|
||||
};
|
||||
contenuto.Controls.Add(lblIstruzioni);
|
||||
|
||||
_btnCreaRaw.Text = "Crea cartella raw";
|
||||
_btnCreaRaw.Margin = new Padding(0, 0, 0, 12);
|
||||
_btnCreaRaw.Margin = new Padding(0, 0, 8, 0);
|
||||
UiStile.Primario(_btnCreaRaw);
|
||||
_btnCreaRaw.Click += (_, _) => CreaCartellaRaw();
|
||||
contenuto.Controls.Add(_btnCreaRaw);
|
||||
rigaCreaRaw.Controls.Add(_btnCreaRaw);
|
||||
rigaCreaRaw.Controls.Add(new Label
|
||||
{
|
||||
AutoSize = true,
|
||||
ForeColor = SystemColors.GrayText,
|
||||
Margin = new Padding(0, 9, 0, 0),
|
||||
Text = "Copia i file dal server nella cartella 'raw'.",
|
||||
});
|
||||
contenuto.Controls.Add(rigaCreaRaw);
|
||||
|
||||
_gridRaw.Dock = DockStyle.Fill;
|
||||
_gridRaw.ReadOnly = true;
|
||||
@@ -526,8 +555,7 @@ public partial class Form1 : Form
|
||||
Margin = new Padding(0, 0, 0, 12),
|
||||
Text = "Gli assiemi referenziano altri PRT e sotto-assiemi al loro interno: premi "
|
||||
+ "qui per risolvere l'albero componenti (ricorsivamente) e copiare tutto ciò che "
|
||||
+ "viene trovato nell'indice dentro 'raw'. Passo opzionale: se la distinta contiene "
|
||||
+ "solo parti singole puoi anche passare direttamente alla fase successiva.",
|
||||
+ "viene trovato nell'indice dentro 'raw'.",
|
||||
};
|
||||
contenuto.Controls.Add(lblIstruzioni);
|
||||
|
||||
@@ -616,7 +644,7 @@ public partial class Form1 : Form
|
||||
{
|
||||
try
|
||||
{
|
||||
var (csv, righe) = DistintaBaseImporter.ConvertiInCsv(percorso, _cartellaLavoro!);
|
||||
var (_, righe) = DistintaBaseImporter.ConvertiInCsv(percorso, _cartellaLavoro!);
|
||||
_percorsoInputCorrente = percorso;
|
||||
_righeCorrenti = righe;
|
||||
|
||||
@@ -629,7 +657,8 @@ public partial class Form1 : Form
|
||||
_ultimaCartellaRaw = null;
|
||||
_ultimaVerifica = null;
|
||||
|
||||
ImpostaStatoImport($"CSV generato ({righe.Count} righe): {csv}", Color.DarkGreen);
|
||||
ImpostaStatoImport("", Color.Black);
|
||||
_rigaVerifica.Visible = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -637,6 +666,7 @@ public partial class Form1 : Form
|
||||
_righeCorrenti = null;
|
||||
_gridImport.Rows.Clear();
|
||||
ImpostaStatoImport($"Errore durante la conversione: {ex.Message}", Color.DarkRed);
|
||||
_rigaVerifica.Visible = false;
|
||||
}
|
||||
AggiornaStatoAvanti();
|
||||
}
|
||||
@@ -664,6 +694,7 @@ public partial class Form1 : Form
|
||||
? Color.FromArgb(198, 239, 206)
|
||||
: Color.FromArgb(255, 199, 206);
|
||||
}
|
||||
AggiornaStatoAvanti();
|
||||
}
|
||||
|
||||
private void CreaCartellaRaw()
|
||||
@@ -707,7 +738,8 @@ public partial class Form1 : Form
|
||||
.ToList();
|
||||
if (cartelle.Count == 0)
|
||||
{
|
||||
ImpostaStatoImport($"Nessuna cartella 'raw' o 'step' trovata in {radice}.", Color.DarkRed);
|
||||
MessageBox.Show(this, $"Nessuna cartella 'raw' o 'step' trovata in {radice}.",
|
||||
"Pulisci raw e step", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -734,7 +766,8 @@ public partial class Form1 : Form
|
||||
}
|
||||
}
|
||||
|
||||
ImpostaStatoImport($"{eliminati} file eliminati da {string.Join(" e ", cartelle)}.", Color.DarkGreen);
|
||||
MessageBox.Show(this, $"{eliminati} file eliminati da {string.Join(" e ", cartelle)}.",
|
||||
"Pulisci raw e step", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
/// <summary>Tutti i codici prt/asm noti all'indice, con i relativi percorsi (ultima
|
||||
@@ -1104,14 +1137,14 @@ public partial class Form1 : Form
|
||||
/// 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,
|
||||
/// 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()
|
||||
{
|
||||
var ultima = LeggiUltimaCartellaLavoro();
|
||||
_cartellaLavoro = ultima is not null && Directory.Exists(ultima)
|
||||
? ultima
|
||||
: (_dbPath is not null ? Path.GetDirectoryName(_dbPath) : null) ?? AppContext.BaseDirectory;
|
||||
AggiornaLabelCartellaLavoro();
|
||||
AggiornaStatoAvanti();
|
||||
}
|
||||
|
||||
private void ScegliCartellaLavoro()
|
||||
@@ -1126,13 +1159,10 @@ public partial class Form1 : Form
|
||||
|
||||
string percorso = dialog.SelectedPath;
|
||||
_cartellaLavoro = percorso;
|
||||
AggiornaLabelCartellaLavoro();
|
||||
SalvaUltimaCartellaLavoro(percorso);
|
||||
AggiornaStatoAvanti();
|
||||
}
|
||||
|
||||
private void AggiornaLabelCartellaLavoro() => _lblCartellaLavoro.Text = $"Cartella di lavoro: {_cartellaLavoro}";
|
||||
|
||||
private static string? LeggiUltimaCartellaLavoro()
|
||||
{
|
||||
try
|
||||
@@ -1173,6 +1203,8 @@ public partial class Form1 : Form
|
||||
_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.";
|
||||
_lblUltimoAggiornamento.Text = "";
|
||||
_dbCaricato = false;
|
||||
_indicatoreDb.Invalidate();
|
||||
AggiornaStatoAvanti();
|
||||
return;
|
||||
}
|
||||
@@ -1217,6 +1249,8 @@ public partial class Form1 : Form
|
||||
MessageBox.Show(this, $"Impossibile aprire il database:\n{ex.Message}", "Errore",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
_dbCaricato = _dbPath is not null;
|
||||
_indicatoreDb.Invalidate();
|
||||
AggiornaStatoAvanti();
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -12,18 +12,22 @@ public class GuidaForm : Form
|
||||
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".
|
||||
|
||||
"File ▸ Nuova estrazione" (Ctrl+N) azzera distinta/raw/verifica per
|
||||
"File ▸ Nuovo" (Ctrl+N) azzera distinta/raw/verifica per
|
||||
ripartire con una nuova distinta base, senza dover ricaricare il database.
|
||||
"""),
|
||||
("1. Database", """
|
||||
Carica o aggiorna l'indice "cad_index.db" a partire dalle cartelle di primo
|
||||
livello del disco/share (radice di default X:\). Qui si sceglie anche la
|
||||
cartella di lavoro, dove finiscono CSV, "raw" e "step".
|
||||
livello del disco/share (radice di default X:\). Un pallino verde/rosso indica
|
||||
se un database è caricato. La cartella di lavoro, dove finiscono CSV, "raw" e
|
||||
"step", si cambia da "File ▸ Scegli cartella di lavoro...".
|
||||
"""),
|
||||
("2. Importa Distinta Base", """
|
||||
Converte il file della distinta (trascinabile nella finestra) in un CSV
|
||||
componente;descrizione nella cartella di lavoro. Se il file segue la
|
||||
convenzione del gestionale, aggiunge anche l'assieme generale come riga.
|
||||
Converte il file della distinta (trascinabile nella finestra, o scelto col
|
||||
bottone "1. Carica la distinta") in un CSV componente;descrizione nella cartella
|
||||
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", """
|
||||
Cerca nell'indice i file CAD dei componenti del CSV e li copia nella
|
||||
|
||||
@@ -15,6 +15,14 @@ public class PrtMancantiForm : Form
|
||||
ClientSize = new Size(720, 440);
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
Font = new Font("Segoe UI", 9.5f);
|
||||
try
|
||||
{
|
||||
Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
|
||||
}
|
||||
catch (Exception ex) when (ex is IOException or ArgumentException)
|
||||
{
|
||||
// ponytail: nessuna icona nell'exe (es. lanciato da dotnet run) -> resta quella di default
|
||||
}
|
||||
|
||||
var lblInfo = new Label
|
||||
{
|
||||
@@ -56,8 +64,17 @@ public class PrtMancantiForm : Form
|
||||
grid.Rows[i].DefaultCellStyle.ForeColor = Color.DarkRed;
|
||||
}
|
||||
|
||||
var btnApriCartella = new Button { Text = "Apri cartella raw", Dock = DockStyle.Bottom, Height = 34 };
|
||||
UiStile.Secondario(btnApriCartella);
|
||||
var (pannelloAzioni, flowAzioni) = UiStile.FloatBar();
|
||||
|
||||
var btnChiudi = new Button { Text = "Chiudi" };
|
||||
UiStile.Primario(btnChiudi);
|
||||
UiStile.Arrotonda(btnChiudi, 10);
|
||||
btnChiudi.Click += (_, _) => Close();
|
||||
flowAzioni.Controls.Add(btnChiudi);
|
||||
|
||||
var btnApriCartella = new Button { Text = "Apri cartella raw", Margin = new Padding(8, 0, 0, 0) };
|
||||
UiStile.SecondarioPieno(btnApriCartella);
|
||||
UiStile.Arrotonda(btnApriCartella, 10);
|
||||
btnApriCartella.Click += (_, _) =>
|
||||
{
|
||||
try { Process.Start("explorer.exe", cartellaRaw); }
|
||||
@@ -67,10 +84,12 @@ public class PrtMancantiForm : Form
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
};
|
||||
flowAzioni.Controls.Add(btnApriCartella);
|
||||
|
||||
Controls.Add(grid);
|
||||
Controls.Add(lblInfo);
|
||||
Controls.Add(btnApriCartella);
|
||||
Controls.Add(pannelloAzioni);
|
||||
CancelButton = btnChiudi;
|
||||
|
||||
Resize += (_, _) => lblInfo.MaximumSize = new Size(ClientSize.Width - 24, 0);
|
||||
}
|
||||
|
||||
+109
-11
@@ -12,6 +12,12 @@ internal static class UiStile
|
||||
/// l'RGB.</summary>
|
||||
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
|
||||
// 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.
|
||||
@@ -48,22 +54,38 @@ internal static class UiStile
|
||||
b.Cursor = Cursors.Hand;
|
||||
}
|
||||
|
||||
/// <summary>Arrotonda gli angoli del bottone. Si aggancia a SizeChanged invece di calcolare
|
||||
/// la Region una volta sola: con AutoSize la dimensione finale si conosce solo a layout
|
||||
/// avvenuto (dopo Text/Padding), non subito dopo la creazione del controllo.</summary>
|
||||
public static void Arrotonda(Button b, int raggio = 6)
|
||||
/// <summary>Come Secondario, ma pieno invece che a bordo: sulle card bianche delle floatbar
|
||||
/// (vedi FloatBar) il bordo sottile di Secondario è quasi invisibile su sfondo bianco, e il
|
||||
/// bottone risulterebbe visivamente diverso dal Primario pieno accanto — stessa costruzione
|
||||
/// (nessun bordo, riempimento pieno), solo grigio chiaro invece che blu.</summary>
|
||||
public static void SecondarioPieno(Button b)
|
||||
{
|
||||
b.SizeChanged += (_, _) => AggiornaRegione(b, raggio);
|
||||
AggiornaRegione(b, raggio);
|
||||
DimensionamentoAutomatico(b);
|
||||
b.FlatStyle = FlatStyle.Flat;
|
||||
b.FlatAppearance.BorderSize = 0;
|
||||
b.FlatAppearance.MouseOverBackColor = Color.FromArgb(230, 233, 237);
|
||||
b.FlatAppearance.MouseDownBackColor = Color.FromArgb(213, 217, 222);
|
||||
b.BackColor = Color.FromArgb(241, 243, 245);
|
||||
b.Cursor = Cursors.Hand;
|
||||
}
|
||||
|
||||
private static void AggiornaRegione(Button b, int raggio)
|
||||
/// <summary>Arrotonda gli angoli del controllo (bottone o card). Si aggancia a SizeChanged
|
||||
/// invece di calcolare la Region una volta sola: con AutoSize la dimensione finale si
|
||||
/// conosce solo a layout avvenuto (dopo Text/Padding), non subito dopo la creazione del
|
||||
/// controllo.</summary>
|
||||
public static void Arrotonda(Control c, int raggio = 6)
|
||||
{
|
||||
if (b.Width <= 0 || b.Height <= 0)
|
||||
c.SizeChanged += (_, _) => AggiornaRegione(c, raggio);
|
||||
AggiornaRegione(c, raggio);
|
||||
}
|
||||
|
||||
private static void AggiornaRegione(Control c, int raggio)
|
||||
{
|
||||
if (c.Width <= 0 || c.Height <= 0)
|
||||
return;
|
||||
|
||||
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();
|
||||
percorso.AddArc(rect.X, rect.Y, d, d, 180, 90);
|
||||
percorso.AddArc(rect.Right - d, rect.Y, d, d, 270, 90);
|
||||
@@ -71,7 +93,83 @@ internal static class UiStile
|
||||
percorso.AddArc(rect.X, rect.Bottom - d, d, d, 90, 90);
|
||||
percorso.CloseFigure();
|
||||
|
||||
b.Region?.Dispose();
|
||||
b.Region = new Region(percorso);
|
||||
c.Region?.Dispose();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Barra di bottoni "flottante" (Avanti/Indietro, Apri cartella raw/Chiudi, ecc.):
|
||||
/// una card bianca staccata su tutti e 4 i lati dal bordo della finestra — non un footer a
|
||||
/// tutta larghezza — con angoli arrotondati e bordo sottile, sospesa sopra lo sfondo grigio
|
||||
/// della pagina invece che ancorata al bordo. Lo sfondo del contenitore esterno deve
|
||||
/// combaciare con quello di default della Form (nessun BackColor impostato altrove:
|
||||
/// SystemColors.Control) perché il "distacco" si veda solo nel margine attorno alla card,
|
||||
/// non in una fascia di colore diverso.</summary>
|
||||
public static (Panel Contenitore, FlowLayoutPanel Bottoni) FloatBar()
|
||||
{
|
||||
// Altezza minima per non tagliare il contenuto: bottone (MinimumSize.Height = 32) +
|
||||
// padding verticale della riga bottoni (12+12) + padding verticale del contenitore
|
||||
// esterno (10+16) = 82, con un po' di margine in più.
|
||||
var contenitore = new Panel
|
||||
{
|
||||
Dock = DockStyle.Bottom,
|
||||
Height = 88,
|
||||
BackColor = SystemColors.Control,
|
||||
Padding = new Padding(16, 10, 16, 16),
|
||||
};
|
||||
|
||||
var card = new Panel { Dock = DockStyle.Fill, BackColor = Color.White };
|
||||
card.Paint += (_, e) =>
|
||||
{
|
||||
using var penna = new Pen(ColoreBordoCard);
|
||||
e.Graphics.DrawRectangle(penna, 0, 0, card.Width - 1, card.Height - 1);
|
||||
};
|
||||
Arrotonda(card, 14);
|
||||
|
||||
var bottoni = new FlowLayoutPanel
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.RightToLeft,
|
||||
Padding = new Padding(16, 12, 16, 12),
|
||||
};
|
||||
|
||||
card.Controls.Add(bottoni);
|
||||
contenitore.Controls.Add(card);
|
||||
return (contenitore, bottoni);
|
||||
}
|
||||
|
||||
/// <summary>Forza le stesse dimensioni per due bottoni della stessa barra (es. Avanti/
|
||||
/// Indietro): AutoSize li dimensiona in base al proprio testo, e con testi di lunghezza
|
||||
/// diversa (o solo uno dei due in grassetto, come Primario/Secondario) risulterebbero
|
||||
/// disallineati sia in larghezza che in altezza — un dettaglio che un designer non
|
||||
/// lascerebbe passare. Va chiamato dopo aver impostato Text/Font su entrambi.</summary>
|
||||
public static void LarghezzaUguale(params Button[] bottoni)
|
||||
{
|
||||
int larghezza = bottoni.Max(b => b.PreferredSize.Width);
|
||||
int altezza = bottoni.Max(b => b.PreferredSize.Height);
|
||||
foreach (var b in bottoni)
|
||||
b.MinimumSize = new Size(larghezza, altezza);
|
||||
}
|
||||
}
|
||||
+42
-20
@@ -92,8 +92,8 @@ trascinano i `.asm` su Creo Distributed Batch, che scrive in `step/`.
|
||||
|
||||
| # | Fase | Bottone → metodo | Cosa fa |
|
||||
|---|---|---|---|
|
||||
| 1 | Database | "Aggiorna indice" → `Indexer.ScanAsync`; "Cambia cartella..." → `ScegliCartellaLavoro` | Crea/aggiorna `cad_index.db` scansionando la share; sceglie/mostra la cartella di lavoro |
|
||||
| 2 | Importa Distinta Base | selezione file → `ImportaDistinta` → `DistintaBaseImporter.ConvertiInCsv` | Xls/Xml gestionale → CSV componente;descrizione, scritto nella 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/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 |
|
||||
| 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) |
|
||||
@@ -102,10 +102,14 @@ trascinano i `.asm` su Creo Distributed Batch, che scrive in `step/`.
|
||||
`_percorsoInputCorrente`, `_righeCorrenti` (righe del CSV), `_ultimaVerifica` (cache percorsi
|
||||
CAD), `_ultimaCartellaRaw`.
|
||||
|
||||
Menu (`MenuStrip`, in cima alla finestra): "File → Nuova estrazione" (Ctrl+N) azzera lo
|
||||
stato delle fasi 2-5 (`NuovaEstrazione`) per ripartire con una nuova distinta senza
|
||||
ricaricare il database/la cartella di lavoro (fase 1, che resta invariata); "Aiuto → Guida"
|
||||
(F1) apre `GuidaForm`, sintesi interattiva delle 5 fasi per chi non ha letto questi docs.
|
||||
Menu (`MenuStrip`, in cima alla finestra): "File → Nuovo" (Ctrl+N) azzera lo
|
||||
stato delle fasi 2-5 (`NuovaEstrazione`) e va direttamente alla fase 2, senza passare dalla
|
||||
fase 1: database e cartella di lavoro restano quelli già caricati, non serve rifare lo scan;
|
||||
"File → Scegli cartella di lavoro..." → `ScegliCartellaLavoro`, cambia in qualunque momento
|
||||
la destinazione di CSV/`raw/`/`step/`; "File → Pulisci raw e step..." svuota le cartelle
|
||||
`raw/`/`step/` nella cartella di lavoro (`PulisciRawEStep`, non tocca l'indice); "Aiuto →
|
||||
Guida" (F1) apre `GuidaForm`, sintesi interattiva delle 5 fasi per chi non ha letto questi
|
||||
docs.
|
||||
|
||||
Altre responsabilità in Form1.cs:
|
||||
- `TrovaPercorsiCad` / `CaricaCodiciNoti` — query sul DB (`files_ultima_versione`), la
|
||||
@@ -189,8 +193,8 @@ completi".
|
||||
file) nelle sole colonne Componente/Descrizione, foglio `"Distinta Base"`. Se il nome del
|
||||
file segue la convenzione `DBP_<codice>_<timestamp>`, aggiunge l'assieme generale come riga
|
||||
in più (il foglio elenca solo i componenti sotto l'assieme). Scrive il CSV nella cartella
|
||||
passata da `Form1` (la cartella di lavoro scelta in fase 1), non necessariamente accanto al
|
||||
file di input.
|
||||
passata da `Form1` (la cartella di lavoro, impostabile da "File → Scegli cartella di lavoro..."),
|
||||
non necessariamente accanto al file di input.
|
||||
|
||||
## Finestre di dialogo (modali, mostrate a fine step)
|
||||
|
||||
@@ -207,9 +211,22 @@ completi".
|
||||
per i secondari, blu pieno per l'azione principale di ogni fase), entrambi con
|
||||
`AutoSize`+`Padding`+`MinimumSize` invece di una `Size` fissa in pixel indovinata a
|
||||
mano (altrimenti il testo va a capo e si taglia in verticale se non ci sta nella
|
||||
larghezza scelta). `Arrotonda` applica angoli arrotondati via `Region` calcolata su
|
||||
`SizeChanged` (non una volta sola: con `AutoSize` la dimensione finale del bottone si
|
||||
conosce solo a layout avvenuto), usata sui bottoni "Avanti"/"Indietro" del wizard.
|
||||
larghezza scelta). `SecondarioPieno` è la variante senza bordo (sfondo grigio chiaro
|
||||
pieno) per i bottoni secondari sopra le card bianche di `Card`/`FloatBar`, dove il
|
||||
bordo sottile di `Secondario` è troppo poco visibile su sfondo bianco. `Arrotonda`
|
||||
applica angoli arrotondati a un `Control` qualsiasi (bottone o card) via `Region`
|
||||
calcolata su `SizeChanged`, non una volta sola: con `AutoSize` la dimensione finale si
|
||||
conosce solo a layout avvenuto — va chiamata dopo aver fissato le dimensioni finali del
|
||||
controllo (es. dopo `LarghezzaUguale`), altrimenti la `Region` vecchia resta visibile
|
||||
come bordo residuo finché non arriva un repaint completo. `Card` costruisce una card di
|
||||
stato (sfondo/bordo distinti, angoli arrotondati), usata in fase 1 per il riepilogo
|
||||
Database. `FloatBar` costruisce la barra di navigazione "flottante" in fondo alle
|
||||
finestre (card bianca staccata su tutti e 4 i lati, non un footer a tutta larghezza):
|
||||
usata per Avanti/Indietro nel wizard e per Chiudi/Apri cartella raw in
|
||||
`PrtMancantiForm`. `LarghezzaUguale` forza la stessa larghezza e altezza tra due
|
||||
bottoni della stessa barra (es. Avanti/Indietro, che altrimenti avrebbero dimensioni
|
||||
diverse: testi di lunghezza diversa, e il font in grassetto di `Primario` richiede più
|
||||
altezza di quello normale di `Secondario`/`SecondarioPieno`).
|
||||
- **app.ico** — icona dell'app, referenziata da `<ApplicationIcon>` nel csproj (icona
|
||||
dell'exe in Esplora risorse/taskbar) e riletta esplicitamente in `Form1.BuildUi()`
|
||||
con `Icon.ExtractAssociatedIcon(Application.ExecutablePath)` per la titlebar, senza
|
||||
@@ -225,15 +242,20 @@ completi".
|
||||
## Persistenza
|
||||
|
||||
- **DB** (`cad_index.db`, SQLite) — vedi tabella `files`/vista `files_ultima_versione` sopra.
|
||||
Percorso: cercato accanto all'eseguibile o nella working directory all'avvio; altrimenti
|
||||
selezionabile con "Apri DB...". Radice disco di scansione di default `X:\`
|
||||
(`Form1.RadiceDiscoDefault`, hardcoded).
|
||||
- **Cartella di lavoro** — salvata in `%AppData%/PrepStep/ultima_cartella_lavoro.txt`
|
||||
(stesso meccanismo del DB sopra), proposta di default `AppContext.BaseDirectory` la prima
|
||||
volta; selezionabile/cambiabile con "Cambia cartella..." in fase 1. Tutti i file generati a
|
||||
valle ci finiscono dentro: il CSV della distinta, `raw/` (CAD dei componenti e
|
||||
sotto-componenti); `step/` non è scritta dall'app ma è dove l'utente esporta gli STEP a
|
||||
mano con Creo Distributed Batch, a partire dai file trascinati da `raw/` in fase 5.
|
||||
Percorso ricordato tra un avvio e l'altro in `%AppData%/PrepStep/ultimo_db.txt`
|
||||
(`SalvaUltimoDbUsato`/`LeggiUltimoDbUsato`), scritto ogni volta che si carica un DB
|
||||
(all'avvio se già noto, oppure da "Apri DB..." o al termine di "Aggiorna indice"); se il
|
||||
file non c'è o punta a un percorso cancellato, `InizializzaDatabase` ripiega su
|
||||
`cad_index.db` accanto all'eseguibile o nella working directory. Radice disco di scansione
|
||||
di default `X:\` (`Form1.RadiceDiscoDefault`, hardcoded).
|
||||
- **Cartella di lavoro** — stesso meccanismo del DB sopra, salvata in
|
||||
`%AppData%/PrepStep/ultima_cartella_lavoro.txt`; se non c'è una preferenza salvata (o punta
|
||||
a una cartella cancellata) si propone la cartella del DB caricato, o in ultima istanza
|
||||
`AppContext.BaseDirectory`; cambiabile in qualunque momento da "File → Scegli cartella di
|
||||
lavoro...". Tutti i file generati a valle ci finiscono dentro: il CSV della distinta, `raw/`
|
||||
(CAD dei componenti e sotto-componenti); `step/` non è scritta dall'app ma è dove l'utente
|
||||
esporta gli STEP a mano con Creo Distributed Batch, a partire dai file trascinati da `raw/`
|
||||
in fase 5.
|
||||
|
||||
## Script standalone (`scripts/`)
|
||||
|
||||
|
||||
Reference in new issue
Block a user