2026-09-16 09:58:55 +02:00
|
|
|
using System.Diagnostics;
|
|
|
|
|
using Microsoft.Data.Sqlite;
|
|
|
|
|
|
|
|
|
|
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();
|
2026-09-16 10:22:07 +02:00
|
|
|
private readonly DataGridView _gridImport = new();
|
|
|
|
|
private readonly Label _lblImportStatus = new();
|
2026-09-16 09:58:55 +02:00
|
|
|
|
|
|
|
|
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:\";
|
|
|
|
|
|
|
|
|
|
private string? _dbPath;
|
|
|
|
|
|
|
|
|
|
public Form1()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
BuildUi();
|
|
|
|
|
Load += (_, _) => InizializzaDatabase();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BuildUi()
|
|
|
|
|
{
|
|
|
|
|
var topPanel = new TableLayoutPanel
|
|
|
|
|
{
|
|
|
|
|
Dock = DockStyle.Top,
|
|
|
|
|
Height = 76,
|
|
|
|
|
ColumnCount = 7,
|
|
|
|
|
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.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) =>
|
|
|
|
|
{
|
|
|
|
|
if (e.KeyCode == Keys.Enter)
|
|
|
|
|
{
|
|
|
|
|
e.SuppressKeyPress = true;
|
|
|
|
|
EseguiRicerca();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_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();
|
|
|
|
|
|
|
|
|
|
_btnApriDb.Text = "Apri DB...";
|
|
|
|
|
_btnApriDb.Dock = DockStyle.Fill;
|
|
|
|
|
_btnApriDb.Click += (_, _) => ScegliDatabase();
|
|
|
|
|
|
|
|
|
|
_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);
|
|
|
|
|
|
|
|
|
|
_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);
|
|
|
|
|
|
2026-09-16 10:22:07 +02:00
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
_lblImportStatus.Dock = DockStyle.Top;
|
|
|
|
|
_lblImportStatus.Height = 24;
|
|
|
|
|
_lblImportStatus.Padding = new Padding(8, 4, 8, 4);
|
|
|
|
|
_lblImportStatus.ForeColor = SystemColors.GrayText;
|
|
|
|
|
|
|
|
|
|
_gridImport.Dock = DockStyle.Fill;
|
|
|
|
|
_gridImport.ReadOnly = true;
|
|
|
|
|
_gridImport.AllowUserToAddRows = false;
|
|
|
|
|
_gridImport.AllowUserToDeleteRows = false;
|
|
|
|
|
_gridImport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
|
|
|
|
|
_gridImport.Columns.Add("componente", "Componente");
|
|
|
|
|
_gridImport.Columns.Add("descrizione", "Descrizione");
|
|
|
|
|
|
|
|
|
|
tab.Controls.Add(_gridImport);
|
|
|
|
|
tab.Controls.Add(_lblImportStatus);
|
|
|
|
|
tab.Controls.Add(btnSfoglia);
|
|
|
|
|
tab.Controls.Add(lblIstruzioni);
|
|
|
|
|
|
|
|
|
|
tab.DragEnter += (_, e) =>
|
|
|
|
|
e.Effect = e.Data?.GetDataPresent(DataFormats.FileDrop) == true
|
|
|
|
|
? DragDropEffects.Copy
|
|
|
|
|
: DragDropEffects.None;
|
|
|
|
|
tab.DragDrop += (_, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (e.Data?.GetData(DataFormats.FileDrop) is string[] { Length: > 0 } file)
|
|
|
|
|
ImportaDistinta(file[0]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return tab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ScegliFileDistinta()
|
|
|
|
|
{
|
|
|
|
|
using var dialog = new OpenFileDialog
|
|
|
|
|
{
|
|
|
|
|
Filter = "File distinta base (*.xls;*.xml)|*.xls;*.xml|Tutti i file|*.*",
|
|
|
|
|
Title = "Seleziona il file Distinta Base",
|
|
|
|
|
};
|
|
|
|
|
if (dialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
ImportaDistinta(dialog.FileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ImportaDistinta(string percorso)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var (csv, righe) = DistintaBaseImporter.ConvertiInCsv(percorso);
|
|
|
|
|
_gridImport.Rows.Clear();
|
|
|
|
|
foreach (var (componente, descrizione) in righe)
|
|
|
|
|
{
|
|
|
|
|
_gridImport.Rows.Add(componente, descrizione);
|
|
|
|
|
}
|
|
|
|
|
_lblImportStatus.ForeColor = Color.DarkGreen;
|
|
|
|
|
_lblImportStatus.Text = $"CSV generato ({righe.Count} righe): {csv}";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_gridImport.Rows.Clear();
|
|
|
|
|
_lblImportStatus.ForeColor = Color.DarkRed;
|
|
|
|
|
_lblImportStatus.Text = $"Errore durante la conversione: {ex.Message}";
|
|
|
|
|
}
|
2026-09-16 09:58:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InizializzaDatabase()
|
|
|
|
|
{
|
|
|
|
|
var candidati = new[]
|
|
|
|
|
{
|
|
|
|
|
Path.Combine(AppContext.BaseDirectory, "cad_index.db"),
|
|
|
|
|
Path.Combine(Directory.GetCurrentDirectory(), "cad_index.db"),
|
|
|
|
|
};
|
|
|
|
|
_dbPath = candidati.FirstOrDefault(File.Exists);
|
|
|
|
|
|
|
|
|
|
if (_dbPath is null)
|
|
|
|
|
{
|
|
|
|
|
_lblStatus.Text = "Database non trovato. Usa 'Apri DB...' per selezionarlo.";
|
|
|
|
|
_lblDb.Text = "Nessun database caricato.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CaricaDatabase(_dbPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ScegliDatabase()
|
|
|
|
|
{
|
|
|
|
|
using var dialog = new OpenFileDialog
|
|
|
|
|
{
|
|
|
|
|
Filter = "Database SQLite (*.db)|*.db|Tutti i file (*.*)|*.*",
|
|
|
|
|
Title = "Seleziona cad_index.db",
|
|
|
|
|
};
|
|
|
|
|
if (dialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
CaricaDatabase(dialog.FileName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CaricaDatabase(string path)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
_lblDb.Text = $"Database: {path} ({totale:N0} file indicizzati)";
|
|
|
|
|
_lblStatus.Text = "Pronto.";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show(this, $"Impossibile aprire il database:\n{ex.Message}", "Errore",
|
|
|
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void AggiornaIndice()
|
|
|
|
|
{
|
|
|
|
|
string dbPath = _dbPath ?? Path.Combine(AppContext.BaseDirectory, "cad_index.db");
|
|
|
|
|
|
|
|
|
|
if (!Directory.Exists(RadiceDiscoDefault))
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show(this, $"Disco non raggiungibile: {RadiceDiscoDefault}", "Errore",
|
|
|
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_btnAggiorna.Enabled = false;
|
|
|
|
|
_btnCerca.Enabled = false;
|
|
|
|
|
_lblStatus.Text = "Aggiornamento indice in corso...";
|
|
|
|
|
|
|
|
|
|
using var cts = new CancellationTokenSource();
|
|
|
|
|
using var dialog = new ProgressForm();
|
|
|
|
|
var progress = new Progress<ScanProgress>(dialog.Aggiorna);
|
|
|
|
|
dialog.Annullato += (_, _) => cts.Cancel();
|
|
|
|
|
|
|
|
|
|
var scanTask = Indexer.ScanAsync(RadiceDiscoDefault, dbPath, progress, cts.Token);
|
|
|
|
|
|
|
|
|
|
// Chiude automaticamente il dialog quando lo scan termina (successo, errore o annullamento)
|
|
|
|
|
_ = scanTask.ContinueWith(_ =>
|
|
|
|
|
{
|
|
|
|
|
if (dialog.Visible)
|
|
|
|
|
{
|
|
|
|
|
dialog.BeginInvoke(dialog.Close);
|
|
|
|
|
}
|
|
|
|
|
}, TaskScheduler.Default);
|
|
|
|
|
|
|
|
|
|
dialog.ShowDialog(this);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await scanTask;
|
|
|
|
|
_lblStatus.Text = "Indice aggiornato.";
|
|
|
|
|
CaricaDatabase(dbPath);
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException)
|
|
|
|
|
{
|
|
|
|
|
_lblStatus.Text = "Aggiornamento annullato.";
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show(this, $"Errore durante l'aggiornamento dell'indice:\n{ex.Message}", "Errore",
|
|
|
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
_lblStatus.Text = "Aggiornamento fallito.";
|
|
|
|
|
}
|
|
|
|
|
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<string[]> 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<string[]>();
|
|
|
|
|
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<string[]> 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)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
string? percorso = _grid.CurrentRow.Cells[0].Value as string;
|
|
|
|
|
if (string.IsNullOrEmpty(percorso))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Process.Start("explorer.exe", $"/select,\"{percorso}\"");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show(this, $"Impossibile aprire Esplora risorse:\n{ex.Message}", "Errore",
|
|
|
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|