2021-03-04 10:44:09 +01:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-07-08 14:35:27 +02:00
|
|
|
|
using System.ComponentModel;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
using System.Drawing;
|
|
|
|
|
|
using System.Drawing.Text;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
2024-10-14 19:57:24 +02:00
|
|
|
|
using System.Reflection;
|
2026-02-14 19:20:25 +01:00
|
|
|
|
using System.Diagnostics;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
using System.Runtime.InteropServices;
|
2025-07-23 15:08:25 +02:00
|
|
|
|
using System.Text;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Windows.Forms;
|
2024-10-14 22:55:52 +02:00
|
|
|
|
using ImageCatalog_2;
|
2026-02-04 23:16:06 +01:00
|
|
|
|
using ImageCatalog_2.Commands;
|
2024-10-14 22:18:03 +02:00
|
|
|
|
using ImageCatalog_2.Services;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
using MaddoShared;
|
2025-07-23 15:08:25 +02:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2026-02-04 23:16:06 +01:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
namespace ImageCatalog;
|
|
|
|
|
|
|
|
|
|
|
|
public partial class MainForm
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2025-07-28 09:49:55 +02:00
|
|
|
|
private readonly DataModel Model;
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
private readonly ILogger<MainForm> _logger;
|
|
|
|
|
|
|
2025-07-28 09:15:45 +02:00
|
|
|
|
private readonly ParametriSetup _parametriSetup;
|
2025-07-28 10:22:08 +02:00
|
|
|
|
private readonly PicSettings _picSettings;
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
|
|
|
|
|
public MainForm(DataModel model, ImageCreationStuff imageCreationStuff, PicSettings picSettings,
|
|
|
|
|
|
ParametriSetup parametriSetup, ILogger<MainForm> logger)
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2025-07-28 09:49:55 +02:00
|
|
|
|
Model = model;
|
2025-07-28 09:15:45 +02:00
|
|
|
|
_parametriSetup = parametriSetup;
|
2025-07-28 10:22:08 +02:00
|
|
|
|
_picSettings = picSettings;
|
2025-07-28 09:00:07 +02:00
|
|
|
|
_logger = logger;
|
|
|
|
|
|
|
|
|
|
|
|
_logger.LogDebug("Start");
|
|
|
|
|
|
|
|
|
|
|
|
InitializeComponent();
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
2026-02-04 23:16:06 +01:00
|
|
|
|
// Set this form as the control for thread marshalling in the DataModel
|
|
|
|
|
|
Model.SetControl(this);
|
|
|
|
|
|
|
|
|
|
|
|
BindControls();
|
2025-07-28 09:00:07 +02:00
|
|
|
|
|
2026-02-14 19:20:25 +01:00
|
|
|
|
// Wire up 'Open folder in Explorer' buttons
|
|
|
|
|
|
btnOpenSourceFolder.Click += BtnOpenSourceFolder_Click;
|
|
|
|
|
|
btnOpenDestFolder.Click += BtnOpenDestFolder_Click;
|
|
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
var version = Assembly.GetExecutingAssembly().GetName().Version;
|
|
|
|
|
|
_Label27.Text = $"Version: {version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
|
|
|
|
|
|
}
|
2024-10-14 22:55:52 +02:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
protected void BindControls()
|
|
|
|
|
|
{
|
2026-02-04 23:16:06 +01:00
|
|
|
|
// 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;
|
2026-02-14 19:20:25 +01:00
|
|
|
|
// Show message requests (from ViewModel validation)
|
|
|
|
|
|
Model.ShowMessageRequested += OnShowMessageRequested;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnShowMessageRequested(object? sender, Tuple<string, string, MessageBoxIcon> args)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (args is null) return;
|
|
|
|
|
|
// Ensure call on UI thread
|
|
|
|
|
|
if (InvokeRequired)
|
|
|
|
|
|
{
|
|
|
|
|
|
Invoke(new Action(() => OnShowMessageRequested(sender, args)));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MessageBox.Show(this, args.Item1, args.Item2, MessageBoxButtons.OK, args.Item3);
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
2025-07-29 11:10:54 +02:00
|
|
|
|
|
2025-07-28 14:45:03 +02:00
|
|
|
|
private void SetDefaults()
|
2025-07-28 09:00:07 +02:00
|
|
|
|
{
|
2026-02-04 22:10:16 +01:00
|
|
|
|
// Bind ComboBoxes to Model using proper data binding
|
2026-02-04 19:48:03 +01:00
|
|
|
|
ComboBox1.DataSource = new List<string>(Model.VerticalPositions);
|
2026-02-04 22:10:16 +01:00
|
|
|
|
ComboBox1.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.VerticalPosition),
|
|
|
|
|
|
false, DataSourceUpdateMode.OnPropertyChanged));
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
|
|
|
|
|
ComboBox2.DataSource = new List<string>(Model.HorizontalAlignments);
|
2026-02-04 22:10:16 +01:00
|
|
|
|
ComboBox2.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.HorizontalAlignment),
|
|
|
|
|
|
false, DataSourceUpdateMode.OnPropertyChanged));
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
|
|
|
|
|
ComboBox3.DataSource = new List<string>(Model.AvailableFonts);
|
2026-02-04 22:10:16 +01:00
|
|
|
|
ComboBox3.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.FontName),
|
|
|
|
|
|
false, DataSourceUpdateMode.OnPropertyChanged));
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
|
|
|
|
|
ComboBox4.DataSource = new List<string>(Model.HorizontalAlignments);
|
2026-02-04 22:10:16 +01:00
|
|
|
|
ComboBox4.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.LogoHorizontalPosition),
|
|
|
|
|
|
false, DataSourceUpdateMode.OnPropertyChanged));
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
|
|
|
|
|
ComboBox5.DataSource = new List<string> { "Alto", "Centro", "Basso" };
|
2026-02-04 22:10:16 +01:00
|
|
|
|
ComboBox5.DataBindings.Add(new Binding("SelectedItem", bindingSource1, nameof(Model.LogoVerticalPosition),
|
|
|
|
|
|
false, DataSourceUpdateMode.OnPropertyChanged));
|
2026-02-04 23:16:06 +01:00
|
|
|
|
|
|
|
|
|
|
// 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));
|
2026-02-04 21:12:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-03-04 10:44:09 +01:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
private void Form1_Load(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
bindingSource1.DataSource = Model;
|
|
|
|
|
|
Application.EnableVisualStyles();
|
2025-07-28 14:45:03 +02:00
|
|
|
|
SetDefaults();
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
_logger.LogInformation("Programma Avviato");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string CalcTime(DateTime timeStart, DateTime timeStop, int numFoto)
|
|
|
|
|
|
{
|
|
|
|
|
|
long timediffH, timediffS;
|
|
|
|
|
|
long timediffM;
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
TimeSpan timeDiff = timeStop - timeStart;
|
|
|
|
|
|
|
|
|
|
|
|
timediffM = (int)timeDiff.TotalMinutes;
|
|
|
|
|
|
timediffS = (int)timeDiff.TotalSeconds;
|
|
|
|
|
|
timediffH = (int)timeDiff.TotalHours;
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
// timediffM = DateAndTime.DateDiff(DateInterval.Minute, timeStart, timeStop);
|
|
|
|
|
|
// timediffS = DateAndTime.DateDiff(DateInterval.Second, timeStart, timeStop);
|
|
|
|
|
|
// timediffH = DateAndTime.DateDiff(DateInterval.Hour, timeStart, timeStop);
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
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;
|
2025-07-29 10:34:23 +02:00
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
return FixPath(dialog.SelectedPath);
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-04 23:16:06 +01:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
private void OnSelectSourceFolderRequested(object sender, EventArgs e)
|
2025-07-28 09:00:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
var dialogResult = SelectFolder(Model.SourcePath);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(dialogResult))
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2025-07-28 09:00:07 +02:00
|
|
|
|
Model.SourcePath = dialogResult;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-14 19:20:25 +01:00
|
|
|
|
private void BtnOpenSourceFolder_Click(object? sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Prefer the model value but fall back to the textbox if needed
|
|
|
|
|
|
var path = string.IsNullOrWhiteSpace(Model.SourcePath) ? txtSorgente.Text : Model.SourcePath;
|
|
|
|
|
|
OpenFolder(path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void BtnOpenDestFolder_Click(object? sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var path = string.IsNullOrWhiteSpace(Model.DestinationPath) ? txtDestinazione.Text : Model.DestinationPath;
|
|
|
|
|
|
OpenFolder(path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OpenFolder(string? path)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show(this, "Folder path is empty.", "Open Folder", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
path = path.Trim().Trim('"');
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (File.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
// If a file was provided, open its folder and select it
|
|
|
|
|
|
Process.Start("explorer.exe", $"/select,\"{path}\"");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Directory.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
Process.Start(new ProcessStartInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
FileName = path,
|
|
|
|
|
|
UseShellExecute = true
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MessageBox.Show(this, $"Folder does not exist: {path}", "Open Folder", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger?.LogError(ex, "Failed to open folder {Path}", path);
|
|
|
|
|
|
MessageBox.Show(this, $"Failed to open folder: {ex.Message}", "Open Folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
private void OnSelectDestinationFolderRequested(object sender, EventArgs e)
|
2025-07-28 09:00:07 +02:00
|
|
|
|
{
|
|
|
|
|
|
var dialogResult = SelectFolder(Model.DestinationPath);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(dialogResult))
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2025-07-28 09:00:07 +02:00
|
|
|
|
Model.DestinationPath = dialogResult;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
private void OnSelectLogoFileRequested(object sender, EventArgs e)
|
2025-07-28 09:00:07 +02:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
var dialog = new OpenFileDialog();
|
|
|
|
|
|
dialog.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
|
|
|
|
|
|
if (Model.LogoFile.Length > 0)
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
dialog.FileName = Model.LogoFile;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
|
|
|
|
|
if (dialog.ShowDialog() == DialogResult.OK)
|
2025-07-28 14:45:03 +02:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
Model.LogoFile = dialog.FileName;
|
|
|
|
|
|
UpdateLogoPictureBox(Model.LogoFile);
|
2025-07-28 14:45:03 +02:00
|
|
|
|
}
|
2026-02-04 19:48:03 +01:00
|
|
|
|
}
|
2025-07-28 14:45:03 +02:00
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
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);
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
2021-03-04 10:44:09 +01:00
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
private async void OnLoadSettingsRequested(object sender, string e)
|
2025-07-28 09:00:07 +02:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
var openDialog = new OpenFileDialog
|
|
|
|
|
|
{
|
|
|
|
|
|
Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*",
|
|
|
|
|
|
FilterIndex = 0,
|
|
|
|
|
|
RestoreDirectory = true
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (openDialog.ShowDialog() != DialogResult.OK) return;
|
|
|
|
|
|
|
2026-02-04 22:10:16 +01:00
|
|
|
|
try
|
2025-09-19 09:53:31 +02:00
|
|
|
|
{
|
2026-02-04 22:10:16 +01:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2026-02-04 19:48:03 +01:00
|
|
|
|
|
2026-02-04 22:10:16 +01:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2026-02-04 19:48:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnSelectColorRequested(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var colorDialog = new ColorDialog
|
|
|
|
|
|
{
|
|
|
|
|
|
AllowFullOpen = true
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(Model.TextColorRGB))
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
colorDialog.Color = ColorTranslator.FromHtml(Model.TextColorRGB);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
// Invalid color, use default
|
|
|
|
|
|
}
|
2025-09-19 09:53:31 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
if (colorDialog.ShowDialog() == DialogResult.OK)
|
2025-09-19 09:53:31 +02:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
Model.TextColorRGB = ColorTranslator.ToHtml(colorDialog.Color);
|
|
|
|
|
|
TextBox34.BackColor = colorDialog.Color;
|
2025-09-19 09:53:31 +02:00
|
|
|
|
}
|
2026-02-04 19:48:03 +01:00
|
|
|
|
}
|
2025-09-19 09:53:31 +02:00
|
|
|
|
|
2026-02-04 19:48:03 +01:00
|
|
|
|
private void UpdateLogoPictureBox(string logoPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
2025-09-19 09:53:31 +02:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
PictureBox1.Image = Image.FromFile(logoPath);
|
2025-09-19 09:53:31 +02:00
|
|
|
|
if (PictureBox1.Image.Height >= PictureBox1.Image.Width)
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2025-09-19 09:53:31 +02:00
|
|
|
|
PictureBox1.Height = 160;
|
2026-02-04 19:48:03 +01:00
|
|
|
|
PictureBox1.Width = (int)(160 * PictureBox1.Image.Width / (double)PictureBox1.Image.Height);
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
2025-07-28 09:00:07 +02:00
|
|
|
|
else
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2026-02-04 19:48:03 +01:00
|
|
|
|
PictureBox1.Width = 160;
|
|
|
|
|
|
PictureBox1.Height = (int)(160 * PictureBox1.Image.Height / (double)PictureBox1.Image.Width);
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
2025-09-19 09:53:31 +02:00
|
|
|
|
}
|
2026-02-04 19:48:03 +01:00
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
// Image loading failed, ignore
|
|
|
|
|
|
}
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
2021-03-04 10:44:09 +01:00
|
|
|
|
|
2025-07-28 09:00:07 +02:00
|
|
|
|
private void setLabel18Text(string text)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Label18.InvokeRequired)
|
2021-03-04 10:44:09 +01:00
|
|
|
|
{
|
2025-07-28 09:00:07 +02:00
|
|
|
|
Label18.Invoke(new Action<string>(setLabel18Text), text);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Label18.Text = text;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
2025-07-28 09:00:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2021-03-04 10:44:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|