Refactor thumbnail options to enum and ComboBox UI

Replaced multiple mutually-exclusive boolean properties for thumbnail text options with a single enum (`ThumbnailOption`) in the data model. Updated WinForms UI to use a ComboBox instead of radio buttons for selecting thumbnail mode. Adjusted designer, mapping profile, settings DTO, and settings service for enum support and backward compatibility. Simplified thumbnail generation logic and improved maintainability by ensuring only one mode can be selected at a time.
This commit is contained in:
MaddoScientisto 2026-02-16 19:55:37 +01:00
commit d13ec8abdf
7 changed files with 214 additions and 289 deletions

View file

@ -227,21 +227,23 @@ public class ImageCreatorSharp(PicSettings picSettings, ILogger<ImageCreatorShar
}
}
private void CreateThumbnails(Image sourceImage, ImageState imgState, Bitmap imgOutputBig, ImageFormat format)
{
if (!picSettings.CreaMiniature || picSettings.AggiungiScritteMiniature)
return;
private void CreateThumbnails(Image sourceImage, ImageState imgState, Bitmap imgOutputBig, ImageFormat format)
{
// Only skip thumbnail generation when the global "create thumbnails" flag is false.
// Whether thumbnails include text is handled by ShouldRenderText/CreateThumbnailWithText
if (!picSettings.CreaMiniature)
return;
PrepareSignatureText(imgState);
PrepareSignatureText(imgState);
if (IsSameDirectory(picSettings.DirectorySorgente, picSettings.DirectoryDestinazione))
UpdateFilenameWithCode(imgState);
if (IsSameDirectory(picSettings.DirectorySorgente, picSettings.DirectoryDestinazione))
UpdateFilenameWithCode(imgState);
if (ShouldRenderText())
CreateThumbnailWithText(sourceImage, imgState, imgOutputBig, format);
else
CreateSimpleThumbnail(sourceImage, imgState, format);
}
if (ShouldRenderText())
CreateThumbnailWithText(sourceImage, imgState, imgOutputBig, format);
else
CreateSimpleThumbnail(sourceImage, imgState, format);
}
private void PrepareSignatureText(ImageState imgState)
{

View file

@ -960,22 +960,16 @@ namespace ImageCatalog_2
private bool _addTimeToThumbnails;
public bool AddTimeToThumbnails
{
get => _addTimeToThumbnails;
get => _thumbnailOption == ThumbnailOptionEnum.Time;
set
{
if (_addTimeToThumbnails == value) return;
_addTimeToThumbnails = value;
if (value)
{
// ensure mutually exclusive choices
_addTextToThumbnails = false;
_showPhotoNumber = false;
_addNumberAndTimeToThumbnails = false;
_addRaceTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
ThumbnailOption = ThumbnailOptionEnum.Time;
}
else if (_thumbnailOption == ThumbnailOptionEnum.Time)
{
ThumbnailOption = ThumbnailOptionEnum.None;
}
NotifyPropertyChanged();
}
@ -984,10 +978,13 @@ namespace ImageCatalog_2
private bool _showFileNameOnThumbnails;
public bool ShowFileNameOnThumbnails
{
get => _showFileNameOnThumbnails;
get => _thumbnailOption == ThumbnailOptionEnum.FileName;
set
{
_showFileNameOnThumbnails = value;
if (value)
ThumbnailOption = ThumbnailOptionEnum.FileName;
else if (_thumbnailOption == ThumbnailOptionEnum.FileName)
ThumbnailOption = ThumbnailOptionEnum.None;
NotifyPropertyChanged();
}
}
@ -1028,23 +1025,13 @@ namespace ImageCatalog_2
private bool _addTextToThumbnails;
public bool AddTextToThumbnails
{
get => _addTextToThumbnails;
get => _thumbnailOption == ThumbnailOptionEnum.Text;
set
{
if (_addTextToThumbnails == value) return;
_addTextToThumbnails = value;
if (value)
{
// ensure mutually exclusive choices
_addTimeToThumbnails = false;
_showPhotoNumber = false;
_addNumberAndTimeToThumbnails = false;
_addRaceTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
}
ThumbnailOption = ThumbnailOptionEnum.Text;
else if (_thumbnailOption == ThumbnailOptionEnum.Text)
ThumbnailOption = ThumbnailOptionEnum.None;
NotifyPropertyChanged();
}
}
@ -1052,23 +1039,13 @@ namespace ImageCatalog_2
private bool _addRaceTimeToThumbnails;
public bool AddRaceTimeToThumbnails
{
get => _addRaceTimeToThumbnails;
get => _thumbnailOption == ThumbnailOptionEnum.RaceTime;
set
{
if (_addRaceTimeToThumbnails == value) return;
_addRaceTimeToThumbnails = value;
if (value)
{
// ensure mutually exclusive choices
_addTimeToThumbnails = false;
_addTextToThumbnails = false;
_showPhotoNumber = false;
_addNumberAndTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
}
ThumbnailOption = ThumbnailOptionEnum.RaceTime;
else if (_thumbnailOption == ThumbnailOptionEnum.RaceTime)
ThumbnailOption = ThumbnailOptionEnum.None;
NotifyPropertyChanged();
}
}
@ -1076,23 +1053,59 @@ namespace ImageCatalog_2
private bool _addNumberAndTimeToThumbnails;
public bool AddNumberAndTimeToThumbnails
{
get => _addNumberAndTimeToThumbnails;
get => _thumbnailOption == ThumbnailOptionEnum.FileNameAndTime;
set
{
if (_addNumberAndTimeToThumbnails == value) return;
_addNumberAndTimeToThumbnails = value;
if (value)
{
// ensure mutually exclusive choices
_addTimeToThumbnails = false;
_addTextToThumbnails = false;
_showPhotoNumber = false;
_addRaceTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
}
ThumbnailOption = ThumbnailOptionEnum.FileNameAndTime;
else if (_thumbnailOption == ThumbnailOptionEnum.FileNameAndTime)
ThumbnailOption = ThumbnailOptionEnum.None;
NotifyPropertyChanged();
}
}
// New enum and authoritative property for thumbnail selection
public enum ThumbnailOptionEnum
{
None = 0,
Text = 1,
FileName = 2,
Time = 3,
FileNameAndTime = 4,
RaceTime = 5
}
private ThumbnailOptionEnum _thumbnailOption = ThumbnailOptionEnum.None;
// Name matches DTO property so SettingsService mapping works
public ThumbnailOptionEnum ThumbnailOption
{
get => _thumbnailOption;
set
{
if (_thumbnailOption == value) return;
_thumbnailOption = value;
// Notify all dependent properties so UI updates
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
NotifyPropertyChanged(nameof(ShowFileNameOnThumbnails));
NotifyPropertyChanged(nameof(ThumbnailMode));
}
}
// Helper int property to bind ComboBox SelectedIndex in the WinForms designer
public int ThumbnailOptionIndex
{
get => (int)ThumbnailOption;
set
{
var opt = (ThumbnailOptionEnum)value;
if (opt == ThumbnailOption) return;
ThumbnailOption = opt;
NotifyPropertyChanged();
}
}
@ -1103,52 +1116,40 @@ namespace ImageCatalog_2
{
get
{
if (AddTextToThumbnails) return "Text";
if (AddTimeToThumbnails) return "Time";
if (ShowPhotoNumber) return "Number";
if (AddNumberAndTimeToThumbnails) return "NumberAndTime";
if (AddRaceTimeToThumbnails) return "RaceTime";
return "None";
return _thumbnailOption switch
{
ThumbnailOptionEnum.Text => "Text",
ThumbnailOptionEnum.Time => "Time",
ThumbnailOptionEnum.FileName => "Number",
ThumbnailOptionEnum.FileNameAndTime => "NumberAndTime",
ThumbnailOptionEnum.RaceTime => "RaceTime",
_ => "None",
};
}
set
{
var current = ThumbnailMode;
if (string.Equals(current, value, StringComparison.OrdinalIgnoreCase)) return;
// Set the boolean flags via their public setters so mutual-exclusion logic runs
// Map incoming string to enum and set the authoritative property
switch ((value ?? string.Empty).ToLowerInvariant())
{
case "text":
AddTextToThumbnails = true;
ThumbnailOption = ThumbnailOptionEnum.Text;
break;
case "time":
AddTimeToThumbnails = true;
ThumbnailOption = ThumbnailOptionEnum.Time;
break;
case "number":
ShowPhotoNumber = true;
ThumbnailOption = ThumbnailOptionEnum.FileName;
break;
case "numberandtime":
AddNumberAndTimeToThumbnails = true;
ThumbnailOption = ThumbnailOptionEnum.FileNameAndTime;
break;
case "racetime":
AddRaceTimeToThumbnails = true;
ThumbnailOption = ThumbnailOptionEnum.RaceTime;
break;
default:
// clear all
_addTimeToThumbnails = false;
_addTextToThumbnails = false;
_showPhotoNumber = false;
_addRaceTimeToThumbnails = false;
_addNumberAndTimeToThumbnails = false;
NotifyPropertyChanged(nameof(AddTimeToThumbnails));
NotifyPropertyChanged(nameof(AddTextToThumbnails));
NotifyPropertyChanged(nameof(ShowPhotoNumber));
NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails));
NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails));
ThumbnailOption = ThumbnailOptionEnum.None;
break;
}
NotifyPropertyChanged(nameof(ThumbnailMode));
}
}

View file

@ -14,7 +14,7 @@ namespace ImageCatalog
// Form overrides dispose to clean up the component list.
[DebuggerNonUserCode()]
protected override void Dispose(bool disposing)
{
{
try
{
if (disposing && components is object)
@ -138,12 +138,6 @@ namespace ImageCatalog
GroupBox1 = new GroupBox();
Label46 = new Label();
TextBox33 = new TextBox();
Panel2 = new Panel();
RadioButton3 = new RadioButton();
RadioButton7 = new RadioButton();
RadioButton4 = new RadioButton();
RadioButton6 = new RadioButton();
RadioButton5 = new RadioButton();
Label5 = new Label();
TextBox5 = new TextBox();
Label6 = new Label();
@ -151,8 +145,11 @@ namespace ImageCatalog
Label3 = new Label();
TextBox3 = new TextBox();
CheckBox1 = new CheckBox();
comboThumbnailOption = new ComboBox();
TabPage4 = new TabPage();
GroupBox6 = new GroupBox();
chkUseTransparentColor = new CheckBox();
btnSetTransparency = new Button();
_PictureBox1 = new PictureBox();
ComboBox5 = new ComboBox();
ComboBox4 = new ComboBox();
@ -169,6 +166,7 @@ namespace ImageCatalog
_Button4 = new Button();
TextBox10 = new TextBox();
Label29 = new Label();
PictureBox3 = new PictureBox();
versionLabel = new Label();
_Button7 = new Button();
_Button5 = new Button();
@ -181,10 +179,8 @@ namespace ImageCatalog
_btnCreaCatalogoAsync = new Button();
timer1 = new System.Windows.Forms.Timer(components);
dataModelBindingSource1 = new BindingSource(components);
PictureBox3 = new PictureBox();
colorDialog1 = new ColorDialog();
btnSetTransparency = new Button();
chkUseTransparentColor = new CheckBox();
label16 = new Label();
((System.ComponentModel.ISupportInitialize)bindingSource1).BeginInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource).BeginInit();
TabControl1.SuspendLayout();
@ -207,12 +203,11 @@ namespace ImageCatalog
TabPage1.SuspendLayout();
Panel1.SuspendLayout();
GroupBox1.SuspendLayout();
Panel2.SuspendLayout();
TabPage4.SuspendLayout();
GroupBox6.SuspendLayout();
((System.ComponentModel.ISupportInitialize)_PictureBox1).BeginInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).BeginInit();
((System.ComponentModel.ISupportInitialize)PictureBox3).BeginInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).BeginInit();
SuspendLayout();
//
// ProgressBar1
@ -1323,9 +1318,9 @@ namespace ImageCatalog
//
// GroupBox1
//
GroupBox1.Controls.Add(label16);
GroupBox1.Controls.Add(Label46);
GroupBox1.Controls.Add(TextBox33);
GroupBox1.Controls.Add(Panel2);
GroupBox1.Controls.Add(Label5);
GroupBox1.Controls.Add(TextBox5);
GroupBox1.Controls.Add(Label6);
@ -1333,6 +1328,7 @@ namespace ImageCatalog
GroupBox1.Controls.Add(Label3);
GroupBox1.Controls.Add(TextBox3);
GroupBox1.Controls.Add(CheckBox1);
GroupBox1.Controls.Add(comboThumbnailOption);
GroupBox1.ForeColor = Color.FromArgb(0, 0, 192);
GroupBox1.Location = new Point(12, 12);
GroupBox1.Margin = new Padding(6, 8, 6, 8);
@ -1362,84 +1358,6 @@ namespace ImageCatalog
TextBox33.Size = new Size(196, 35);
TextBox33.TabIndex = 20;
//
// Panel2
//
Panel2.Controls.Add(RadioButton3);
Panel2.Controls.Add(RadioButton7);
Panel2.Controls.Add(RadioButton4);
Panel2.Controls.Add(RadioButton6);
Panel2.Controls.Add(RadioButton5);
Panel2.Location = new Point(113, 262);
Panel2.Margin = new Padding(6, 8, 6, 8);
Panel2.Name = "Panel2";
Panel2.Size = new Size(470, 207);
Panel2.TabIndex = 19;
//
// RadioButton3
//
RadioButton3.AutoSize = true;
RadioButton3.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTextToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton3.Location = new Point(30, 38);
RadioButton3.Margin = new Padding(6, 8, 6, 8);
RadioButton3.Name = "RadioButton3";
RadioButton3.Size = new Size(186, 34);
RadioButton3.TabIndex = 14;
RadioButton3.TabStop = true;
RadioButton3.Text = "Aggiungi Scritta";
RadioButton3.UseVisualStyleBackColor = true;
//
// RadioButton7
//
RadioButton7.AutoSize = true;
RadioButton7.DataBindings.Add(new Binding("Checked", bindingSource1, "AddNumberAndTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton7.Location = new Point(258, 93);
RadioButton7.Margin = new Padding(6, 8, 6, 8);
RadioButton7.Name = "RadioButton7";
RadioButton7.Size = new Size(184, 34);
RadioButton7.TabIndex = 18;
RadioButton7.TabStop = true;
RadioButton7.Text = "numero+tempo";
RadioButton7.UseVisualStyleBackColor = true;
//
// RadioButton4
//
RadioButton4.AutoSize = true;
RadioButton4.DataBindings.Add(new Binding("Checked", bindingSource1, "AddTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton4.Location = new Point(30, 93);
RadioButton4.Margin = new Padding(6, 8, 6, 8);
RadioButton4.Name = "RadioButton4";
RadioButton4.Size = new Size(182, 34);
RadioButton4.TabIndex = 15;
RadioButton4.TabStop = true;
RadioButton4.Text = "Aggiungi orario";
RadioButton4.UseVisualStyleBackColor = true;
//
// RadioButton6
//
RadioButton6.AutoSize = true;
RadioButton6.DataBindings.Add(new Binding("Checked", bindingSource1, "ShowPhotoNumber", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton6.Location = new Point(258, 38);
RadioButton6.Margin = new Padding(6, 8, 6, 8);
RadioButton6.Name = "RadioButton6";
RadioButton6.Size = new Size(158, 34);
RadioButton6.TabIndex = 17;
RadioButton6.TabStop = true;
RadioButton6.Text = "Numero foto";
RadioButton6.UseVisualStyleBackColor = true;
//
// RadioButton5
//
RadioButton5.AutoSize = true;
RadioButton5.DataBindings.Add(new Binding("Checked", bindingSource1, "AddRaceTimeToThumbnails", true, DataSourceUpdateMode.OnPropertyChanged));
RadioButton5.Location = new Point(30, 150);
RadioButton5.Margin = new Padding(6, 8, 6, 8);
RadioButton5.Name = "RadioButton5";
RadioButton5.Size = new Size(149, 34);
RadioButton5.TabIndex = 16;
RadioButton5.TabStop = true;
RadioButton5.Text = "Tempo Gara";
RadioButton5.UseVisualStyleBackColor = true;
//
// Label5
//
Label5.AutoSize = true;
@ -1514,6 +1432,15 @@ namespace ImageCatalog
CheckBox1.TabIndex = 5;
CheckBox1.Text = "Crea miniature";
//
// comboThumbnailOption
//
comboThumbnailOption.DropDownStyle = ComboBoxStyle.DropDownList;
comboThumbnailOption.Location = new Point(204, 262);
comboThumbnailOption.Margin = new Padding(6, 8, 6, 8);
comboThumbnailOption.Name = "comboThumbnailOption";
comboThumbnailOption.Size = new Size(470, 38);
comboThumbnailOption.TabIndex = 18;
//
// TabPage4
//
TabPage4.Controls.Add(GroupBox6);
@ -1557,6 +1484,25 @@ namespace ImageCatalog
GroupBox6.TabStop = false;
GroupBox6.Text = "Logo";
//
// chkUseTransparentColor
//
chkUseTransparentColor.AutoSize = true;
chkUseTransparentColor.Location = new Point(39, 461);
chkUseTransparentColor.Name = "chkUseTransparentColor";
chkUseTransparentColor.Size = new Size(210, 34);
chkUseTransparentColor.TabIndex = 46;
chkUseTransparentColor.Text = "Colore trasparente";
chkUseTransparentColor.UseVisualStyleBackColor = true;
//
// btnSetTransparency
//
btnSetTransparency.Location = new Point(288, 455);
btnSetTransparency.Name = "btnSetTransparency";
btnSetTransparency.Size = new Size(131, 40);
btnSetTransparency.TabIndex = 45;
btnSetTransparency.Text = "Imposta";
btnSetTransparency.UseVisualStyleBackColor = true;
//
// _PictureBox1
//
_PictureBox1.Cursor = Cursors.Cross;
@ -1729,6 +1675,17 @@ namespace ImageCatalog
Label29.Text = "Posizione orizzontale";
Label29.TextAlign = ContentAlignment.MiddleLeft;
//
// PictureBox3
//
PictureBox3.BorderStyle = BorderStyle.FixedSingle;
PictureBox3.Location = new Point(432, 442);
PictureBox3.Margin = new Padding(6, 8, 6, 8);
PictureBox3.Name = "PictureBox3";
PictureBox3.Size = new Size(45, 53);
PictureBox3.TabIndex = 44;
PictureBox3.TabStop = false;
PictureBox3.Visible = false;
//
// versionLabel
//
versionLabel.DataBindings.Add(new Binding("Text", bindingSource1, "AppVersion", true));
@ -1844,35 +1801,14 @@ namespace ImageCatalog
//
dataModelBindingSource1.DataSource = typeof(ImageCatalog_2.DataModel);
//
// PictureBox3
// label16
//
PictureBox3.BorderStyle = BorderStyle.FixedSingle;
PictureBox3.Location = new Point(432, 442);
PictureBox3.Margin = new Padding(6, 8, 6, 8);
PictureBox3.Name = "PictureBox3";
PictureBox3.Size = new Size(45, 53);
PictureBox3.TabIndex = 44;
PictureBox3.TabStop = false;
PictureBox3.Visible = false;
//
// btnSetTransparency
//
btnSetTransparency.Location = new Point(288, 455);
btnSetTransparency.Name = "btnSetTransparency";
btnSetTransparency.Size = new Size(131, 40);
btnSetTransparency.TabIndex = 45;
btnSetTransparency.Text = "Imposta";
btnSetTransparency.UseVisualStyleBackColor = true;
//
// chkUseTransparentColor
//
chkUseTransparentColor.AutoSize = true;
chkUseTransparentColor.Location = new Point(39, 461);
chkUseTransparentColor.Name = "chkUseTransparentColor";
chkUseTransparentColor.Size = new Size(210, 34);
chkUseTransparentColor.TabIndex = 46;
chkUseTransparentColor.Text = "Colore trasparente";
chkUseTransparentColor.UseVisualStyleBackColor = true;
label16.AutoSize = true;
label16.Location = new Point(39, 262);
label16.Name = "label16";
label16.Size = new Size(156, 30);
label16.TabIndex = 22;
label16.Text = "Testo Miniature";
//
// MainForm
//
@ -1933,14 +1869,12 @@ namespace ImageCatalog
Panel1.PerformLayout();
GroupBox1.ResumeLayout(false);
GroupBox1.PerformLayout();
Panel2.ResumeLayout(false);
Panel2.PerformLayout();
TabPage4.ResumeLayout(false);
GroupBox6.ResumeLayout(false);
GroupBox6.PerformLayout();
((System.ComponentModel.ISupportInitialize)_PictureBox1).EndInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).EndInit();
((System.ComponentModel.ISupportInitialize)PictureBox3).EndInit();
((System.ComponentModel.ISupportInitialize)dataModelBindingSource1).EndInit();
ResumeLayout(false);
PerformLayout();
}
@ -2126,12 +2060,7 @@ namespace ImageCatalog
internal GroupBox GroupBox1;
internal Label Label46;
internal TextBox TextBox33;
internal Panel Panel2;
internal RadioButton RadioButton3;
internal RadioButton RadioButton7;
internal RadioButton RadioButton4;
internal RadioButton RadioButton6;
internal RadioButton RadioButton5;
private ComboBox comboThumbnailOption;
internal Label Label5;
internal TextBox TextBox5;
internal Label Label6;
@ -2295,6 +2224,7 @@ namespace ImageCatalog
private ColorDialog colorDialog1;
private Button btnSetTransparency;
private CheckBox chkUseTransparentColor;
private Label label16;
internal Button btnCreaCatalogoAsync
{

View file

@ -83,54 +83,21 @@ public partial class MainForm
// Watch for model changes so we can reflect external updates
Model.PropertyChanged += Model_PropertyChanged;
// Fix thumbnail radio buttons: clear designer bindings to avoid binding vs click conflicts
RadioButton3.DataBindings.Clear();
RadioButton4.DataBindings.Clear();
RadioButton5.DataBindings.Clear();
RadioButton6.DataBindings.Clear();
RadioButton7.DataBindings.Clear();
// Thumbnail options moved to ComboBox to avoid conflicting bindings with multiple radio buttons
// Initialize radio state from model (thumbnail options)
try
{
_suppressRadioUpdates = true;
RadioButton3.Checked = Model.AddTextToThumbnails;
RadioButton4.Checked = Model.AddTimeToThumbnails;
RadioButton6.Checked = Model.ShowPhotoNumber;
RadioButton7.Checked = Model.AddNumberAndTimeToThumbnails;
RadioButton5.Checked = Model.AddRaceTimeToThumbnails;
}
finally
{
_suppressRadioUpdates = false;
}
// Initialize ComboBox with Italian descriptions
comboThumbnailOption.Items.Clear();
comboThumbnailOption.Items.AddRange(new object[] {
"Nessuna",
"Aggiungi scritta",
"Nome file",
"Aggiungi orario",
"Nome+Orario",
"Tempo gara"
});
// Use CheckedChanged handlers to set the authoritative ThumbnailMode on the model
RadioButton3.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton3.Checked) Model.ThumbnailMode = "Text";
};
RadioButton4.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton4.Checked) Model.ThumbnailMode = "Time";
};
RadioButton6.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton6.Checked) Model.ThumbnailMode = "Number";
};
RadioButton7.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton7.Checked) Model.ThumbnailMode = "NumberAndTime";
};
RadioButton5.CheckedChanged += (s, ev) =>
{
if (_suppressRadioUpdates) return;
if (RadioButton5.Checked) Model.ThumbnailMode = "RaceTime";
};
// Bind to model via helper index property ThumbnailOptionIndex
comboThumbnailOption.DataBindings.Add(new Binding("SelectedIndex", bindingSource1, "ThumbnailOptionIndex", true, DataSourceUpdateMode.OnPropertyChanged));
// Save user preferences on form close instead of immediately when dialogs are used
this.FormClosing += MainForm_FormClosing;
@ -185,22 +152,15 @@ public partial class MainForm
}
}
// Thumbnail mode changes - reflect back to radio buttons
// Thumbnail mode changes - reflect back to combo box index
if (e.PropertyName == nameof(Model.ThumbnailMode) ||
e.PropertyName == nameof(Model.AddTextToThumbnails) ||
e.PropertyName == nameof(Model.AddTimeToThumbnails) ||
e.PropertyName == nameof(Model.ShowPhotoNumber) ||
e.PropertyName == nameof(Model.AddNumberAndTimeToThumbnails) ||
e.PropertyName == nameof(Model.AddRaceTimeToThumbnails))
e.PropertyName == nameof(Model.ThumbnailOption) ||
e.PropertyName == nameof(Model.ThumbnailOptionIndex))
{
try
{
_suppressRadioUpdates = true;
RadioButton3.Checked = Model.AddTextToThumbnails;
RadioButton4.Checked = Model.AddTimeToThumbnails;
RadioButton6.Checked = Model.ShowPhotoNumber;
RadioButton7.Checked = Model.AddNumberAndTimeToThumbnails;
RadioButton5.Checked = Model.AddRaceTimeToThumbnails;
comboThumbnailOption.SelectedIndex = Model.ThumbnailOptionIndex;
}
finally
{

View file

@ -70,15 +70,15 @@ public class DataModelMappingProfile : Profile
.ForMember(dest => dest.OverwriteFiles, opt => opt.MapFrom(src => src.OverwriteImages))
// Additional settings
.ForMember(dest => dest.UsaOrarioMiniatura, opt => opt.MapFrom(src => src.AddTimeToThumbnails))
.ForMember(dest => dest.UsaOrarioMiniatura, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.Time))
.ForMember(dest => dest.DataPartenza, opt => opt.MapFrom(src => src.RaceStartDate))
.ForMember(dest => dest.TestoOrario, opt => opt.MapFrom(src => src.TimeLabel))
.ForMember(dest => dest.TestoMin, opt => opt.MapFrom(src => src.ShowFileNameOnThumbnails))
.ForMember(dest => dest.TestoMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.FileName))
// Thumbnail text options
.ForMember(dest => dest.AggiungiScritteMiniature, opt => opt.MapFrom(src => src.AddTextToThumbnails))
.ForMember(dest => dest.AggTempoGaraMin, opt => opt.MapFrom(src => src.AddRaceTimeToThumbnails))
.ForMember(dest => dest.AggNumTempMin, opt => opt.MapFrom(src => src.AddNumberAndTimeToThumbnails))
.ForMember(dest => dest.AggiungiScritteMiniature, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.Text))
.ForMember(dest => dest.AggTempoGaraMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.RaceTime))
.ForMember(dest => dest.AggNumTempMin, opt => opt.MapFrom(src => src.ThumbnailOption == ImageCatalog_2.DataModel.ThumbnailOptionEnum.FileNameAndTime))
// Ignore unmapped properties
.ForMember(dest => dest.DestDir, opt => opt.Ignore())

View file

@ -10,6 +10,21 @@ namespace ImageCatalog_2.Models
/// </summary>
public class SettingsDto
{
// New enum to represent thumbnail mode in a single property.
public enum ThumbnailOptionDto
{
None = 0,
Text = 1,
FileName = 2,
Time = 3,
FileNameAndTime = 4,
RaceTime = 5
}
[JsonPropertyName("ThumbnailOption")]
[XmlElement("MiniatureModalita")]
public ThumbnailOptionDto ThumbnailOption { get; set; } = ThumbnailOptionDto.None;
// Paths
[JsonPropertyName("SourcePath")]
[XmlElement("DirSorgente")]

View file

@ -75,7 +75,7 @@ namespace ImageCatalog_2.Services
try
{
object value;
if (prop.PropertyType == typeof(string))
if (prop.PropertyType == typeof(string))
{
value = fileParams.LeggiParametroString(xmlName);
}
@ -83,6 +83,22 @@ namespace ImageCatalog_2.Services
{
value = fileParams.LeggiParametroBoolean(xmlName);
}
else if (prop.PropertyType.IsEnum)
{
// Read enum as string from XML and try to parse to the enum type. Fall back to default.
var str = fileParams.LeggiParametroString(xmlName);
try
{
var enumValue = Enum.Parse(prop.PropertyType, str ?? string.Empty, true);
value = enumValue;
}
catch
{
// try numeric
var intVal = fileParams.LeggiParametro<int>(xmlName, (int)(prop.GetValue(loadedDto) ?? 0));
value = Enum.ToObject(prop.PropertyType, intVal);
}
}
else if (prop.PropertyType == typeof(int))
{
value = fileParams.LeggiParametro<int>(xmlName, (int)(prop.GetValue(loadedDto) ?? 0));
@ -117,6 +133,7 @@ namespace ImageCatalog_2.Services
}
return loadedDto;
// End of LoadSettingsAsync method
});
// Step 2: Apply DTO values to ViewModel on UI thread