Add explicit working folder; rename project from CadSearchGui to PrepStep

Working folder (phase 1): CSV/raw/step/step_finali all used to live split
across two different implicit locations (CSV in the "repo root" found by
walking up for CLAUDE.md, raw/step next to the input distinta file) with
neither shown to the user. That repo-root lookup also silently breaks once
the app runs as a standalone published exe on a machine with no repo/
CLAUDE.md at all. Replaced both with one explicit "cartella di lavoro",
auto-suggested (last used, remembered the same way as the DB path) and
changeable from phase 1, with no dependency on any repo marker file.

Rename: CadSearchGui was the working name from before the app had a
product identity; renamed folders, csproj files, namespace and the
AppData settings folder to PrepStep throughout, matching the exe name
already in use. Product-facing name stays "Cevolani StepPrep".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5 committed 2026-09-21 11:18:43 +02:00
1 parent 6726dd2216
commit 13798ad47c
24 files changed
+211 -129

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
namespace PrepStep;
public sealed class ProgressForm : Form
{
private readonly Label _lblCartella = new();
private readonly ProgressBar _progressBar = new();
private readonly Label _lblConteggio = new();
private readonly Label _lblDettaglio = new();
private readonly Label _lblEta = new();
private readonly Button _btnAnnulla = new();
private readonly ToolTip _tipCartella = new();
public event EventHandler? Annullato;
public ProgressForm()
{
Text = "Aggiornamento indice in corso...";
FormBorderStyle = FormBorderStyle.FixedDialog;
StartPosition = FormStartPosition.CenterParent;
MinimizeBox = false;
MaximizeBox = false;
ControlBox = false;
ClientSize = new Size(460, 190);
_lblCartella.Text = "Preparazione...";
_lblCartella.Location = new Point(16, 16);
// AutoSize=false + AutoEllipsis: un percorso lungo (share di rete) va troncato con "..."
// invece di sforare il bordo del dialog, che è FixedDialog e non si può allargare.
// Il testo completo resta disponibile nel tooltip (stesso pattern di Form1._lblImportStatus).
_lblCartella.AutoSize = false;
_lblCartella.AutoEllipsis = true;
_lblCartella.Size = new Size(428, 20);
_lblCartella.Font = new Font(Font, FontStyle.Bold);
_progressBar.Location = new Point(16, 44);
_progressBar.Size = new Size(428, 24);
_progressBar.Minimum = 0;
_progressBar.Maximum = 1000;
_progressBar.Style = ProgressBarStyle.Marquee;
_lblConteggio.Location = new Point(16, 80);
_lblConteggio.AutoSize = true;
_lblDettaglio.Location = new Point(16, 104);
_lblDettaglio.AutoSize = true;
_lblDettaglio.ForeColor = SystemColors.GrayText;
_lblEta.Location = new Point(16, 128);
_lblEta.AutoSize = true;
_lblEta.Font = new Font(Font, FontStyle.Bold);
_btnAnnulla.Text = "Annulla";
_btnAnnulla.Location = new Point(354, 152);
_btnAnnulla.Size = new Size(90, 28);
UiStile.Secondario(_btnAnnulla);
_btnAnnulla.Click += (_, e) => Annullato?.Invoke(this, e);
Controls.AddRange(new Control[]
{
_lblCartella, _progressBar, _lblConteggio, _lblDettaglio, _lblEta, _btnAnnulla
});
}
public void Aggiorna(ScanProgress p)
{
_lblCartella.Text = $"Scansione {p.Cartella}...";
_tipCartella.SetToolTip(_lblCartella, _lblCartella.Text);
if (p.PrevistiTotali > 0)
{
_progressBar.Style = ProgressBarStyle.Continuous;
double frazione = Math.Min(1.0, (double)p.FattiTotali / p.PrevistiTotali);
_progressBar.Value = (int)(frazione * _progressBar.Maximum);
}
else
{
_progressBar.Style = ProgressBarStyle.Marquee;
}
_lblConteggio.Text = p.PrevistiTotali > 0
? $"{p.FattiTotali:N0} / ~{p.PrevistiTotali:N0} file"
: $"{p.FattiTotali:N0} file processati";
_lblDettaglio.Text = $"nuovi: {p.Nuovi:N0} aggiornati: {p.Aggiornati:N0} invariati: {p.Invariati:N0}"
+ (p.Rimossi > 0 ? $" rimossi: {p.Rimossi:N0}" : "");
_lblEta.Text = $"Trascorso: {FormatTempo(p.Trascorso)} — {StimaRimanente(p)}";
}
private static string StimaRimanente(ScanProgress p)
{
if (p.PrevistiTotali <= 0 || p.FattiTotali <= 0)
{
return "stima non disponibile";
}
double filePerSecondo = p.FattiTotali / Math.Max(p.Trascorso.TotalSeconds, 0.001);
if (filePerSecondo <= 0)
{
return "stima non disponibile";
}
long rimanenti = Math.Max(p.PrevistiTotali - p.FattiTotali, 0);
var eta = TimeSpan.FromSeconds(rimanenti / filePerSecondo);
return $"tempo rimanente stimato: {FormatTempo(eta)}";
}
private static string FormatTempo(TimeSpan t)
{
if (t.TotalHours >= 1)
{
return $"{(int)t.TotalHours}h {t.Minutes}m {t.Seconds}s";
}
if (t.TotalMinutes >= 1)
{
return $"{t.Minutes}m {t.Seconds}s";
}
return $"{t.Seconds}s";
}
}