Catalog/imagecatalog/MainForm.cs
2026-02-04 23:16:06 +01:00

333 lines
No EOL
11 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ImageCatalog_2;
using ImageCatalog_2.Commands;
using ImageCatalog_2.Services;
using MaddoShared;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
namespace ImageCatalog;
public partial class MainForm
{
private readonly DataModel Model;
private readonly ILogger<MainForm> _logger;
private readonly ParametriSetup _parametriSetup;
private readonly PicSettings _picSettings;
public MainForm(DataModel model, ImageCreationStuff imageCreationStuff, PicSettings picSettings,
ParametriSetup parametriSetup, ILogger<MainForm> logger)
{
Model = model;
_parametriSetup = parametriSetup;
_picSettings = picSettings;
_logger = logger;
_logger.LogDebug("Start");
InitializeComponent();
// Set this form as the control for thread marshalling in the DataModel
Model.SetControl(this);
BindControls();
var version = Assembly.GetExecutingAssembly().GetName().Version;
_Label27.Text = $"Version: {version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
}
protected void BindControls()
{
// Bind buttons to ViewModel commands using command binding
_btnCreaCatalogoAsync.BindCommand(Model.ProcessImagesCommand);
button1.BindCommand(Model.ProcessImagesCommand);
_Button2.BindCommand(Model.SelectSourceFolderCommand);
_Button3.BindCommand(Model.SelectDestinationFolderCommand);
_Button4.BindCommand(Model.SelectLogoFileCommand);
_Button5.BindCommand(Model.SaveSettingsCommand);
_Button6.BindCommand(Model.LoadSettingsCommand);
_Button8.BindCommand(Model.SelectColorCommand);
// Subscribe to ViewModel events for UI dialogs (these need UI context)
Model.SelectSourceFolderRequested += OnSelectSourceFolderRequested;
Model.SelectDestinationFolderRequested += OnSelectDestinationFolderRequested;
Model.SelectLogoFileRequested += OnSelectLogoFileRequested;
Model.SaveSettingsRequested += OnSaveSettingsRequested;
Model.LoadSettingsRequested += OnLoadSettingsRequested;
Model.SelectColorRequested += OnSelectColorRequested;
}
private void SetDefaults()
{
// Bind ComboBoxes to Model using proper data binding
ComboBox1.DataSource = new List<string>(Model.VerticalPositions);
ComboBox1.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.VerticalPosition),
false, DataSourceUpdateMode.OnPropertyChanged));
ComboBox2.DataSource = new List<string>(Model.HorizontalAlignments);
ComboBox2.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.HorizontalAlignment),
false, DataSourceUpdateMode.OnPropertyChanged));
ComboBox3.DataSource = new List<string>(Model.AvailableFonts);
ComboBox3.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.FontName),
false, DataSourceUpdateMode.OnPropertyChanged));
ComboBox4.DataSource = new List<string>(Model.HorizontalAlignments);
ComboBox4.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.LogoHorizontalPosition),
false, DataSourceUpdateMode.OnPropertyChanged));
ComboBox5.DataSource = new List<string> { "Alto", "Centro", "Basso" };
ComboBox5.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.LogoVerticalPosition),
false, DataSourceUpdateMode.OnPropertyChanged));
// Bind progress bar and status labels
ProgressBar1.DataBindings.Add(new Binding("Maximum", bindingSource1, nameof(Model.ProgressBarMaximum),
false, DataSourceUpdateMode.OnPropertyChanged));
ProgressBar1.DataBindings.Add(new Binding("Value", bindingSource1, nameof(Model.ProgressBarValue),
false, DataSourceUpdateMode.OnPropertyChanged));
Label18.DataBindings.Add(new Binding("Text", bindingSource1, nameof(Model.ProcessedImagesCount),
false, DataSourceUpdateMode.OnPropertyChanged));
lblFotoTotaliNum.DataBindings.Add(new Binding("Text", bindingSource1, nameof(Model.TotalImagesCount),
false, DataSourceUpdateMode.OnPropertyChanged));
Label10.DataBindings.Add(new Binding("Text", bindingSource1, nameof(Model.ProcessingStatus),
false, DataSourceUpdateMode.OnPropertyChanged));
}
private void Form1_Load(object sender, EventArgs e)
{
bindingSource1.DataSource = Model;
Application.EnableVisualStyles();
SetDefaults();
_logger.LogInformation("Programma Avviato");
}
private string CalcTime(DateTime timeStart, DateTime timeStop, int numFoto)
{
long timediffH, timediffS;
long timediffM;
TimeSpan timeDiff = timeStop - timeStart;
timediffM = (int)timeDiff.TotalMinutes;
timediffS = (int)timeDiff.TotalSeconds;
timediffH = (int)timeDiff.TotalHours;
// timediffM = DateAndTime.DateDiff(DateInterval.Minute, timeStart, timeStop);
// timediffS = DateAndTime.DateDiff(DateInterval.Second, timeStart, timeStop);
// timediffH = DateAndTime.DateDiff(DateInterval.Hour, timeStart, timeStop);
double fotoSec = numFoto / (double)timediffS;
double fotoMin = numFoto / (double)timediffM;
double fotoOra = numFoto / (double)timediffH;
string s = "S: " + timediffS.ToString() + "; F/s: " +
fotoSec.ToString(
"0.000"); // + " F/m: " + fotoMin.ToString("0.00") + " F/h: " + fotoOra.ToString("0.00")
return s;
}
private string SelectFolder(string startingFolder)
{
var dialog = new FolderBrowserDialog();
dialog.InitialDirectory = startingFolder;
if (dialog.ShowDialog() != DialogResult.OK) return string.Empty;
return FixPath(dialog.SelectedPath);
}
private string FixPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
return string.Empty;
}
// Trim leading/trailing quotes
path = path.Trim().Trim('"');
// Normalize directory separators
path = path.Replace('/', Path.DirectorySeparatorChar)
.Replace('\\', Path.DirectorySeparatorChar);
// Remove trailing separators then add one back
path = path.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
return path;
}
private void OnSelectSourceFolderRequested(object sender, EventArgs e)
{
var dialogResult = SelectFolder(Model.SourcePath);
if (!string.IsNullOrWhiteSpace(dialogResult))
{
Model.SourcePath = dialogResult;
}
}
private void OnSelectDestinationFolderRequested(object sender, EventArgs e)
{
var dialogResult = SelectFolder(Model.DestinationPath);
if (!string.IsNullOrWhiteSpace(dialogResult))
{
Model.DestinationPath = dialogResult;
}
}
private void OnSelectLogoFileRequested(object sender, EventArgs e)
{
var dialog = new OpenFileDialog();
dialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (Model.LogoFile.Length > 0)
{
dialog.FileName = Model.LogoFile;
}
if (dialog.ShowDialog() == DialogResult.OK)
{
Model.LogoFile = dialog.FileName;
UpdateLogoPictureBox(Model.LogoFile);
}
}
private async void OnSaveSettingsRequested(object sender, string e)
{
var saveDialog = new SaveFileDialog
{
Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*",
FilterIndex = 0,
RestoreDirectory = true
};
if (saveDialog.ShowDialog() != DialogResult.OK) return;
await Model.SaveSettingsToFileAsync(saveDialog.FileName);
Text = "Image Catalog - " + Path.GetFileName(saveDialog.FileName);
}
private async void OnLoadSettingsRequested(object sender, string e)
{
var openDialog = new OpenFileDialog
{
Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*",
FilterIndex = 0,
RestoreDirectory = true
};
if (openDialog.ShowDialog() != DialogResult.OK) return;
try
{
await Model.LoadSettingsFromFileAsync(openDialog.FileName);
// Explicitly ensure UI is enabled after loading
Model.UiEnabled = true;
// Update logo preview if logo file exists
if (File.Exists(Model.LogoFile))
{
UpdateLogoPictureBox(Model.LogoFile);
}
Text = "Image Catalog - " + Path.GetFileName(openDialog.FileName);
_logger.LogInformation($"Settings loaded successfully from {openDialog.FileName}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error loading settings");
MessageBox.Show($"Error loading settings: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void OnSelectColorRequested(object sender, EventArgs e)
{
var colorDialog = new ColorDialog
{
AllowFullOpen = true
};
if (!string.IsNullOrWhiteSpace(Model.TextColorRGB))
{
try
{
colorDialog.Color = ColorTranslator.FromHtml(Model.TextColorRGB);
}
catch
{
// Invalid color, use default
}
}
if (colorDialog.ShowDialog() == DialogResult.OK)
{
Model.TextColorRGB = ColorTranslator.ToHtml(colorDialog.Color);
TextBox34.BackColor = colorDialog.Color;
}
}
private void UpdateLogoPictureBox(string logoPath)
{
try
{
PictureBox1.Image = Image.FromFile(logoPath);
if (PictureBox1.Image.Height >= PictureBox1.Image.Width)
{
PictureBox1.Height = 160;
PictureBox1.Width = (int)(160 * PictureBox1.Image.Width / (double)PictureBox1.Image.Height);
}
else
{
PictureBox1.Width = 160;
PictureBox1.Height = (int)(160 * PictureBox1.Image.Height / (double)PictureBox1.Image.Width);
}
}
catch
{
// Image loading failed, ignore
}
}
private void setLabel18Text(string text)
{
if (Label18.InvokeRequired)
{
Label18.Invoke(new Action<string>(setLabel18Text), text);
}
else
{
Label18.Text = text;
}
}
}
public class PicInfo
{
public DirectoryInfo DirSource, DirDest, DirDestStart;
public string NomeImmagine;
public PicInfo(DirectoryInfo Dir_Source, DirectoryInfo Dir_Dest, DirectoryInfo Dir_DestStart,
string Nome_Immagine)
{
DirSource = Dir_Source;
DirDest = Dir_Dest;
DirDestStart = Dir_DestStart;
NomeImmagine = Nome_Immagine;
}
}