diff --git a/CadSearchGui/Form1.cs b/CadSearchGui/Form1.cs
index 05345c2..99cb14c 100644
--- a/CadSearchGui/Form1.cs
+++ b/CadSearchGui/Form1.cs
@@ -5,21 +5,13 @@ namespace CadSearchGui;
public partial class Form1 : Form
{
- private readonly TextBox _txtCerca = new();
- private readonly ComboBox _cmbTipo = new();
- private readonly ComboBox _cmbCartella = new();
- private readonly CheckBox _chkUltima = new();
- private readonly Button _btnCerca = new();
private readonly Button _btnApriDb = new();
private readonly Button _btnAggiorna = new();
- private readonly DataGridView _grid = new();
private readonly Label _lblStatus = new();
private readonly Label _lblDb = new();
private readonly DataGridView _gridImport = new();
private readonly Label _lblImportStatus = new();
- private const string OpzionePrtAsm = "Solo prt/asm (predefinito)";
- private const string OpzioneTuttiTipi = "Tutti i tipi";
private static readonly string[] TipiPredefiniti = { "prt", "asm" };
private const string RadiceDiscoDefault = @"X:\";
@@ -34,122 +26,53 @@ public partial class Form1 : Form
private void BuildUi()
{
+ AllowDrop = true;
+ Text = "Distinta Base -> CSV con percorsi CAD";
+
var topPanel = new TableLayoutPanel
{
Dock = DockStyle.Top,
- Height = 76,
- ColumnCount = 7,
+ Height = 108,
+ ColumnCount = 3,
+ RowCount = 3,
Padding = new Padding(8),
- RowCount = 2,
};
- topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40));
- topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 15));
- topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 20));
+ topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 130));
- topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 90));
- topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 110));
topPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 130));
- _txtCerca.Dock = DockStyle.Fill;
- _txtCerca.Font = new Font(_txtCerca.Font!.FontFamily, 11f);
- _txtCerca.PlaceholderText = "Cerca per codice o nome file (es. 9231000036)...";
- _txtCerca.KeyDown += (_, e) =>
+ var lblIstruzioni = new Label
{
- if (e.KeyCode == Keys.Enter)
- {
- e.SuppressKeyPress = true;
- EseguiRicerca();
- }
+ Dock = DockStyle.Fill,
+ AutoSize = false,
+ Text = "Trascina qui il file .xls/.xml esportato dal gestionale (foglio 'Distinta "
+ + "Base'), oppure scegli il file col pulsante 'Scegli file...'. Viene generato "
+ + "un CSV con Componente/Descrizione e, per ogni componente, il percorso del "
+ + "file CAD corrispondente trovato nell'indice.",
};
+ topPanel.SetColumnSpan(lblIstruzioni, 3);
+ topPanel.Controls.Add(lblIstruzioni, 0, 0);
- _cmbTipo.Dock = DockStyle.Fill;
- _cmbTipo.DropDownStyle = ComboBoxStyle.DropDownList;
- _cmbTipo.Items.Add(OpzionePrtAsm);
- _cmbTipo.Items.Add(OpzioneTuttiTipi);
-
- _cmbCartella.Dock = DockStyle.Fill;
- _cmbCartella.DropDownStyle = ComboBoxStyle.DropDownList;
- _cmbCartella.Items.Add("Tutte le cartelle");
- _cmbCartella.Items.AddRange(new object[] { "__Accessori", "__B.end", "__Corpi", "__Fondi" });
- _cmbCartella.SelectedIndex = 0;
-
- _chkUltima.Text = "Solo ultima versione";
- _chkUltima.Dock = DockStyle.Fill;
- _chkUltima.TextAlign = ContentAlignment.MiddleLeft;
- _chkUltima.Checked = true;
-
- _btnCerca.Text = "Cerca";
- _btnCerca.Dock = DockStyle.Fill;
- _btnCerca.Click += (_, _) => EseguiRicerca();
+ var btnSfoglia = new Button { Text = "Scegli file distinta...", Dock = DockStyle.Fill };
+ btnSfoglia.Click += (_, _) => ScegliFileDistinta();
+ topPanel.Controls.Add(btnSfoglia, 0, 1);
_btnApriDb.Text = "Apri DB...";
_btnApriDb.Dock = DockStyle.Fill;
_btnApriDb.Click += (_, _) => ScegliDatabase();
+ topPanel.Controls.Add(_btnApriDb, 1, 1);
_btnAggiorna.Text = "Aggiorna indice";
_btnAggiorna.Dock = DockStyle.Fill;
_btnAggiorna.Click += (_, _) => AggiornaIndice();
-
- topPanel.Controls.Add(_txtCerca, 0, 0);
- topPanel.Controls.Add(_cmbTipo, 1, 0);
- topPanel.Controls.Add(_cmbCartella, 2, 0);
- topPanel.Controls.Add(_chkUltima, 3, 0);
- topPanel.Controls.Add(_btnCerca, 4, 0);
- topPanel.Controls.Add(_btnApriDb, 5, 0);
- topPanel.Controls.Add(_btnAggiorna, 6, 0);
- topPanel.SetColumnSpan(_lblDb, 7);
+ topPanel.Controls.Add(_btnAggiorna, 2, 1);
_lblDb.Dock = DockStyle.Fill;
_lblDb.AutoSize = false;
_lblDb.ForeColor = SystemColors.GrayText;
_lblDb.TextAlign = ContentAlignment.MiddleLeft;
- topPanel.Controls.Add(_lblDb, 0, 1);
-
- _grid.Dock = DockStyle.Fill;
- _grid.ReadOnly = true;
- _grid.AllowUserToAddRows = false;
- _grid.AllowUserToDeleteRows = false;
- _grid.AllowUserToResizeRows = false;
- _grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
- _grid.MultiSelect = false;
- _grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
- _grid.CellDoubleClick += (_, e) => ApriCartellaFileSelezionato();
-
- var statusPanel = new Panel { Dock = DockStyle.Bottom, Height = 28 };
- _lblStatus.Dock = DockStyle.Fill;
- _lblStatus.TextAlign = ContentAlignment.MiddleLeft;
- _lblStatus.Padding = new Padding(8, 0, 0, 0);
- _lblStatus.Text = "Pronto.";
- statusPanel.Controls.Add(_lblStatus);
-
- var tabRicerca = new TabPage("Ricerca CAD");
- tabRicerca.Controls.Add(_grid);
- tabRicerca.Controls.Add(statusPanel);
- tabRicerca.Controls.Add(topPanel);
-
- var tabs = new TabControl { Dock = DockStyle.Fill };
- tabs.TabPages.Add(BuildTabImportaDistinta());
- tabs.TabPages.Add(tabRicerca);
-
- Controls.Add(tabs);
- }
-
- private TabPage BuildTabImportaDistinta()
- {
- var tab = new TabPage("Importa Distinta Base") { AllowDrop = true };
-
- var lblIstruzioni = new Label
- {
- Dock = DockStyle.Top,
- Height = 60,
- Padding = new Padding(8),
- Text = "Trascina qui il file .xls/.xml esportato dal gestionale (foglio 'Distinta "
- + "Base'), oppure scegli il file col pulsante sotto. VerrĂ generato un CSV con "
- + "le colonne Componente e Descrizione, con anteprima qui sotto.",
- };
-
- var btnSfoglia = new Button { Text = "Scegli file...", Dock = DockStyle.Top, Height = 32 };
- btnSfoglia.Click += (_, _) => ScegliFileDistinta();
+ topPanel.SetColumnSpan(_lblDb, 3);
+ topPanel.Controls.Add(_lblDb, 0, 2);
_lblImportStatus.Dock = DockStyle.Top;
_lblImportStatus.Height = 24;
@@ -160,26 +83,35 @@ public partial class Form1 : Form
_gridImport.ReadOnly = true;
_gridImport.AllowUserToAddRows = false;
_gridImport.AllowUserToDeleteRows = false;
+ _gridImport.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
+ _gridImport.MultiSelect = false;
_gridImport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
_gridImport.Columns.Add("componente", "Componente");
_gridImport.Columns.Add("descrizione", "Descrizione");
+ _gridImport.Columns.Add("percorso", "Percorso CAD");
+ _gridImport.CellDoubleClick += (_, _) => ApriCartellaFileSelezionato();
- tab.Controls.Add(_gridImport);
- tab.Controls.Add(_lblImportStatus);
- tab.Controls.Add(btnSfoglia);
- tab.Controls.Add(lblIstruzioni);
+ var statusPanel = new Panel { Dock = DockStyle.Bottom, Height = 28 };
+ _lblStatus.Dock = DockStyle.Fill;
+ _lblStatus.TextAlign = ContentAlignment.MiddleLeft;
+ _lblStatus.Padding = new Padding(8, 0, 0, 0);
+ _lblStatus.Text = "Pronto.";
+ statusPanel.Controls.Add(_lblStatus);
- tab.DragEnter += (_, e) =>
+ Controls.Add(_gridImport);
+ Controls.Add(_lblImportStatus);
+ Controls.Add(statusPanel);
+ Controls.Add(topPanel);
+
+ DragEnter += (_, e) =>
e.Effect = e.Data?.GetDataPresent(DataFormats.FileDrop) == true
? DragDropEffects.Copy
: DragDropEffects.None;
- tab.DragDrop += (_, e) =>
+ DragDrop += (_, e) =>
{
if (e.Data?.GetData(DataFormats.FileDrop) is string[] { Length: > 0 } file)
ImportaDistinta(file[0]);
};
-
- return tab;
}
private void ScegliFileDistinta()
@@ -198,13 +130,22 @@ public partial class Form1 : Form
try
{
var (csv, righe) = DistintaBaseImporter.ConvertiInCsv(percorso);
+ var percorsiTrovati = TrovaPercorsiCad(righe.Select(r => r.Componente));
+
_gridImport.Rows.Clear();
+ int trovati = 0;
foreach (var (componente, descrizione) in righe)
{
- _gridImport.Rows.Add(componente, descrizione);
+ string percorsoCad = percorsiTrovati.TryGetValue(componente, out var lista)
+ ? string.Join("; ", lista)
+ : "";
+ if (percorsoCad.Length > 0)
+ trovati++;
+ _gridImport.Rows.Add(componente, descrizione, percorsoCad);
}
+
_lblImportStatus.ForeColor = Color.DarkGreen;
- _lblImportStatus.Text = $"CSV generato ({righe.Count} righe): {csv}";
+ _lblImportStatus.Text = $"CSV generato ({righe.Count} righe, {trovati} con percorso CAD trovato): {csv}";
}
catch (Exception ex)
{
@@ -214,6 +155,46 @@ public partial class Form1 : Form
}
}
+ /// Cerca, per ogni codice componente, i percorsi dei file CAD (ultima versione,
+ /// solo prt/asm) corrispondenti nell'indice.
+ private Dictionary> TrovaPercorsiCad(IEnumerable codici)
+ {
+ var risultato = new Dictionary>();
+ if (_dbPath is null)
+ return risultato;
+
+ using var connection = new SqliteConnection($"Data Source={_dbPath};Mode=ReadOnly");
+ connection.Open();
+
+ var nomiParametri = TipiPredefiniti.Select((_, i) => $"@tipo{i}");
+ using var command = connection.CreateCommand();
+ command.CommandText = $"""
+ SELECT percorso_completo FROM files_ultima_versione
+ WHERE codice = @codice AND tipo_file IN ({string.Join(",", nomiParametri)})
+ ORDER BY tipo_file
+ """;
+ var pCodice = command.Parameters.Add("@codice", Microsoft.Data.Sqlite.SqliteType.Text);
+ for (int i = 0; i < TipiPredefiniti.Length; i++)
+ {
+ command.Parameters.AddWithValue($"@tipo{i}", TipiPredefiniti[i]);
+ }
+
+ foreach (var codice in codici.Distinct())
+ {
+ pCodice.Value = codice;
+ using var reader = command.ExecuteReader();
+ var percorsi = new List();
+ while (reader.Read())
+ {
+ percorsi.Add(reader.GetString(0));
+ }
+ if (percorsi.Count > 0)
+ risultato[codice] = percorsi;
+ }
+
+ return risultato;
+ }
+
private void InizializzaDatabase()
{
var candidati = new[]
@@ -253,20 +234,6 @@ public partial class Form1 : Form
using var connection = new SqliteConnection($"Data Source={path};Mode=ReadOnly");
connection.Open();
- _cmbTipo.Items.Clear();
- _cmbTipo.Items.Add(OpzionePrtAsm);
- _cmbTipo.Items.Add(OpzioneTuttiTipi);
- using (var cmd = connection.CreateCommand())
- {
- cmd.CommandText = "SELECT DISTINCT tipo_file FROM files ORDER BY tipo_file";
- using var reader = cmd.ExecuteReader();
- while (reader.Read())
- {
- _cmbTipo.Items.Add(reader.GetString(0));
- }
- }
- _cmbTipo.SelectedIndex = 0;
-
long totale = (long)(new SqliteCommand("SELECT COUNT(*) FROM files", connection).ExecuteScalar() ?? 0L);
_dbPath = path;
@@ -292,7 +259,6 @@ public partial class Form1 : Form
}
_btnAggiorna.Enabled = false;
- _btnCerca.Enabled = false;
_lblStatus.Text = "Aggiornamento indice in corso...";
using var cts = new CancellationTokenSource();
@@ -332,160 +298,24 @@ public partial class Form1 : Form
finally
{
_btnAggiorna.Enabled = true;
- _btnCerca.Enabled = true;
- }
- }
-
- private void EseguiRicerca()
- {
- if (_dbPath is null)
- {
- _lblStatus.Text = "Nessun database caricato. Usa 'Apri DB...'.";
- return;
- }
-
- string testo = _txtCerca.Text.Trim();
- string? tipoSelezionato = (string?)_cmbTipo.SelectedItem;
- string[]? tipi = tipoSelezionato switch
- {
- OpzionePrtAsm => TipiPredefiniti,
- OpzioneTuttiTipi => null,
- null => TipiPredefiniti,
- _ => new[] { tipoSelezionato },
- };
- string? cartella = _cmbCartella.SelectedIndex > 0 ? (string)_cmbCartella.SelectedItem! : null;
- bool soloUltima = _chkUltima.Checked;
-
- if (testo.Length == 0 && tipi is null && cartella is null)
- {
- _lblStatus.Text = "Inserisci un termine di ricerca o imposta un filtro.";
- return;
- }
-
- Cursor = Cursors.WaitCursor;
- _btnCerca.Enabled = false;
- try
- {
- var (colonne, righe, troncato) = Cerca(_dbPath, testo, soloUltima, cartella, tipi);
- PopolaGriglia(colonne, righe);
- _lblStatus.Text = $"{righe.Count} risultat{(righe.Count == 1 ? "o" : "i")}"
- + (troncato ? " (troncato a 500, affina la ricerca)" : "");
- }
- catch (Exception ex)
- {
- MessageBox.Show(this, $"Errore durante la ricerca:\n{ex.Message}", "Errore",
- MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- Cursor = Cursors.Default;
- _btnCerca.Enabled = true;
- }
- }
-
- private static (string[] colonne, List righe, bool troncato) Cerca(
- string dbPath, string testo, bool soloUltimaVersione, string? cartella, string[]? tipi)
- {
- using var connection = new SqliteConnection($"Data Source={dbPath};Mode=ReadOnly");
- connection.Open();
-
- string tabella = soloUltimaVersione ? "files_ultima_versione" : "files";
- string filtroTipo = "1=1";
- if (tipi is { Length: > 0 })
- {
- var nomiParametri = tipi.Select((_, i) => $"@tipo{i}");
- filtroTipo = $"tipo_file IN ({string.Join(",", nomiParametri)})";
- }
-
- var sql = $"""
- SELECT percorso_completo, cartella_radice, famiglia, codice, tipo_file, versione,
- dimensione_byte, data_modifica
- FROM {tabella}
- WHERE (@testo = '' OR codice LIKE @like OR nome_file LIKE @like)
- AND (@cartella IS NULL OR cartella_radice = @cartella)
- AND ({filtroTipo})
- ORDER BY codice, tipo_file, versione
- LIMIT 500
- """;
-
- using var command = connection.CreateCommand();
- command.CommandText = sql;
- command.Parameters.AddWithValue("@testo", testo);
- command.Parameters.AddWithValue("@like", $"%{testo}%");
- command.Parameters.AddWithValue("@cartella", (object?)cartella ?? DBNull.Value);
- if (tipi is { Length: > 0 })
- {
- for (int i = 0; i < tipi.Length; i++)
- {
- command.Parameters.AddWithValue($"@tipo{i}", tipi[i]);
- }
- }
-
- using var reader = command.ExecuteReader();
- var righe = new List();
- while (reader.Read())
- {
- righe.Add(new[]
- {
- reader.GetString(0),
- reader.IsDBNull(2) ? "" : reader.GetString(2),
- reader.IsDBNull(3) ? "" : reader.GetString(3),
- reader.IsDBNull(4) ? "" : reader.GetString(4),
- reader.IsDBNull(5) ? "" : reader.GetInt64(5).ToString(),
- FormatSize(reader.IsDBNull(6) ? 0 : reader.GetInt64(6)),
- reader.IsDBNull(7) ? "" : reader.GetString(7),
- });
- }
-
- var colonne = new[] { "percorso", "famiglia", "codice", "tipo", "ver", "dimensione", "data modifica" };
- return (colonne, righe, righe.Count == 500);
- }
-
- private static string FormatSize(long bytes)
- {
- string[] unita = { "B", "KB", "MB", "GB" };
- double value = bytes;
- int i = 0;
- while (value >= 1024 && i < unita.Length - 1)
- {
- value /= 1024;
- i++;
- }
- return $"{value:0.#} {unita[i]}";
- }
-
- private void PopolaGriglia(string[] colonne, List righe)
- {
- _grid.Rows.Clear();
- _grid.Columns.Clear();
- foreach (var nome in colonne)
- {
- _grid.Columns.Add(nome, nome);
- }
- foreach (var riga in righe)
- {
- _grid.Rows.Add(riga);
- }
- if (_grid.Columns.Count > 0)
- {
- _grid.Columns[0].FillWeight = 220;
}
}
private void ApriCartellaFileSelezionato()
{
- if (_grid.CurrentRow is null)
+ if (_gridImport.CurrentRow is null)
{
return;
}
- string? percorso = _grid.CurrentRow.Cells[0].Value as string;
- if (string.IsNullOrEmpty(percorso))
+ string? percorsi = _gridImport.CurrentRow.Cells[2].Value as string;
+ if (string.IsNullOrEmpty(percorsi))
{
return;
}
+ string primoPercorso = percorsi.Split("; ", 2)[0];
try
{
- Process.Start("explorer.exe", $"/select,\"{percorso}\"");
+ Process.Start("explorer.exe", $"/select,\"{primoPercorso}\"");
}
catch (Exception ex)
{