diff --git a/imagecatalog/DataModel.cs b/imagecatalog/DataModel.cs index 683d296..a138109 100644 --- a/imagecatalog/DataModel.cs +++ b/imagecatalog/DataModel.cs @@ -836,8 +836,22 @@ namespace ImageCatalog_2 get => _showPhotoNumber; set { + if (_showPhotoNumber == value) return; _showPhotoNumber = value; + if (value) + { + // ensure mutually exclusive choices + _addTimeToThumbnails = false; + _addTextToThumbnails = false; + _addNumberAndTimeToThumbnails = false; + _addRaceTimeToThumbnails = false; + NotifyPropertyChanged(nameof(AddTimeToThumbnails)); + NotifyPropertyChanged(nameof(AddTextToThumbnails)); + NotifyPropertyChanged(nameof(AddNumberAndTimeToThumbnails)); + NotifyPropertyChanged(nameof(AddRaceTimeToThumbnails)); + } NotifyPropertyChanged(); + NotifyPropertyChanged(nameof(ThumbnailMode)); } } @@ -949,7 +963,20 @@ namespace ImageCatalog_2 get => _addTimeToThumbnails; 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)); + } NotifyPropertyChanged(); } } @@ -1004,7 +1031,20 @@ namespace ImageCatalog_2 get => _addTextToThumbnails; 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)); + } NotifyPropertyChanged(); } } @@ -1015,7 +1055,20 @@ namespace ImageCatalog_2 get => _addRaceTimeToThumbnails; 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)); + } NotifyPropertyChanged(); } } @@ -1026,11 +1079,79 @@ namespace ImageCatalog_2 get => _addNumberAndTimeToThumbnails; 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)); + } NotifyPropertyChanged(); } } + // Single authoritative thumbnail mode string to avoid conflicting bindings + // Possible values: "None", "Text", "Time", "Number", "NumberAndTime", "RaceTime" + public string ThumbnailMode + { + get + { + if (AddTextToThumbnails) return "Text"; + if (AddTimeToThumbnails) return "Time"; + if (ShowPhotoNumber) return "Number"; + if (AddNumberAndTimeToThumbnails) return "NumberAndTime"; + if (AddRaceTimeToThumbnails) return "RaceTime"; + return "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 + switch ((value ?? string.Empty).ToLowerInvariant()) + { + case "text": + AddTextToThumbnails = true; + break; + case "time": + AddTimeToThumbnails = true; + break; + case "number": + ShowPhotoNumber = true; + break; + case "numberandtime": + AddNumberAndTimeToThumbnails = true; + break; + case "racetime": + AddRaceTimeToThumbnails = true; + 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)); + break; + } + + NotifyPropertyChanged(nameof(ThumbnailMode)); + } + } + // Image processing progress and status private string _processingStatus = ""; public string ProcessingStatus @@ -1132,6 +1253,24 @@ namespace ImageCatalog_2 // Update PicSettings from DataModel using AutoMapper _mapper.Map(this, _picSettings); + // Explicitly ensure thumbnail-related flags are applied to PicSettings + // because AutoMapper may not map differently-named properties. + try + { + _picSettings.AggiungiScritteMiniature = this.AddTextToThumbnails; + _picSettings.UsaOrarioMiniatura = this.AddTimeToThumbnails; + _picSettings.AggNumTempMin = this.AddNumberAndTimeToThumbnails; + _picSettings.AggTempoGaraMin = this.AddRaceTimeToThumbnails; + _picSettings.CreaMiniature = this.CreateThumbnails; + _picSettings.LarghezzaSmall = this.ThumbnailWidth; + _picSettings.AltezzaSmall = this.ThumbnailHeight; + _picSettings.DimMin = this.FontSizeThumbnail; + _picSettings.JpegQualityMin = this.JpegQualityThumbnail; + } + catch + { + // Best-effort; do not fail processing on mapping issues + } var imageCreationOptions = new ImageCreationStuff.Options { diff --git a/imagecatalog/MainForm.Designer.cs b/imagecatalog/MainForm.Designer.cs index edb3bb1..136241c 100644 --- a/imagecatalog/MainForm.Designer.cs +++ b/imagecatalog/MainForm.Designer.cs @@ -1404,6 +1404,7 @@ namespace ImageCatalog // 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"; @@ -1416,6 +1417,7 @@ namespace ImageCatalog // 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"; diff --git a/imagecatalog/MainForm.cs b/imagecatalog/MainForm.cs index 684a60c..674f29d 100644 --- a/imagecatalog/MainForm.cs +++ b/imagecatalog/MainForm.cs @@ -83,6 +83,55 @@ 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(); + + // 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; + } + + // 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"; + }; + // Save user preferences on form close instead of immediately when dialogs are used this.FormClosing += MainForm_FormClosing; @@ -135,6 +184,29 @@ public partial class MainForm _suppressRadioUpdates = false; } } + + // Thumbnail mode changes - reflect back to radio buttons + 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)) + { + 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; + } + } } protected void BindControls() diff --git a/imagecatalog/Program.cs b/imagecatalog/Program.cs index 067acb5..678864c 100644 --- a/imagecatalog/Program.cs +++ b/imagecatalog/Program.cs @@ -79,24 +79,24 @@ static class Program // the block below and comment out the WPF branch. // ----------------------------------------------------------------------------- // // Force WinForms UI (uncomment to enable) - // var mainForm = serviceProvider.GetRequiredService(); - // // If you want to set the DataModel explicitly on the WinForms form use the lines below - // // var mainViewModel = serviceProvider.GetRequiredService(); - // // mainForm.Model = mainViewModel; - // Application.Run(mainForm); + var mainForm = serviceProvider.GetRequiredService(); + // If you want to set the DataModel explicitly on the WinForms form use the lines below + // var mainViewModel = serviceProvider.GetRequiredService(); + // mainForm.Model = mainViewModel; + Application.Run(mainForm); // ----------------------------------------------------------------------------- - if (serviceProvider.GetService(typeof(ImageCatalog_2.MainWindow)) is ImageCatalog_2.MainWindow wpfMain) - { - // Start WPF app - var app = new System.Windows.Application(); - app.Run(wpfMain); - } - else - { - var mainForm = serviceProvider.GetRequiredService(); - Application.Run(mainForm); - } + //if (serviceProvider.GetService(typeof(ImageCatalog_2.MainWindow)) is ImageCatalog_2.MainWindow wpfMain) + //{ + // // Start WPF app + // var app = new System.Windows.Application(); + // app.Run(wpfMain); + //} + //else + //{ + // var mainForm = serviceProvider.GetRequiredService(); + // Application.Run(mainForm); + //} } private static void ConfigureServices(ServiceCollection services)