diff --git a/source/ChanSort.Api/Controller/Editor.cs b/source/ChanSort.Api/Controller/Editor.cs index d007cd2..06ef45f 100644 --- a/source/ChanSort.Api/Controller/Editor.cs +++ b/source/ChanSort.Api/Controller/Editor.cs @@ -524,5 +524,50 @@ namespace ChanSort.Api } #endregion + #region EnforceTvBeforeRadioBeforeData() + public bool EnforceTvBeforeRadioBeforeData() + { + bool hadOverlaps = false; + + foreach (var list in this.DataRoot.ChannelLists) + { + // separate channels into lists for TV, radio and data + var listByServiceType = new List[3]; // TV/Radio/Data, min/max + for (int i = 0; i < 3; i++) + listByServiceType[i] = new(); + + foreach (var ch in list.Channels) + { + if (ch.IsDeleted || ch.NewProgramNr < 0 || ch.IsProxy) + continue; + var serviceType = ch.SignalSource & SignalSource.MaskTvRadioData; + var i = serviceType == SignalSource.Tv ? 0 : serviceType == SignalSource.Radio ? 1 : 2; + listByServiceType[i].Add(ch); + } + + // sort the lists by the new program number + for (int i=0; i<3; i++) + listByServiceType[i].Sort((a,b) => a.NewProgramNr.CompareTo(b.NewProgramNr)); + + // make sure that program numbers are strictly increasing (so that there are no overlaps between the tv/radio/data groups) + var lastNr = listByServiceType[0].Count == 0 ? 0 : listByServiceType[0].Last().NewProgramNr; + for (var i = 1; i <= 2; i++) + { + foreach (var ch in listByServiceType[i]) + { + if (ch.NewProgramNr <= lastNr) + { + ch.NewProgramNr = ++lastNr; + hadOverlaps = true; + } + else + lastNr = ch.NewProgramNr; + } + } + } + + return hadOverlaps; + } + #endregion } } diff --git a/source/ChanSort.Api/Controller/SerializerBase.cs b/source/ChanSort.Api/Controller/SerializerBase.cs index b5291af..1a4e8a6 100644 --- a/source/ChanSort.Api/Controller/SerializerBase.cs +++ b/source/ChanSort.Api/Controller/SerializerBase.cs @@ -37,6 +37,7 @@ namespace ChanSort.Api public bool CanHaveGaps { get; set; } = true; public bool EncryptedFlagEdit { get; set; } public DeleteMode DeleteMode { get; set; } = DeleteMode.NotSupported; + public bool EnforceTvBeforeRadioBeforeData { get; set; } = false; public FavoritesMode FavoritesMode diff --git a/source/ChanSort.Loader.Panasonic/IdtvChannelSerializer.cs b/source/ChanSort.Loader.Panasonic/IdtvChannelSerializer.cs index 1d0e878..43c6514 100644 --- a/source/ChanSort.Loader.Panasonic/IdtvChannelSerializer.cs +++ b/source/ChanSort.Loader.Panasonic/IdtvChannelSerializer.cs @@ -133,6 +133,7 @@ internal class IdtvChannelSerializer : SerializerBase this.Features.FavoritesMode = FavoritesMode.Flags; this.Features.DeleteMode = DeleteMode.FlagWithPrNr; + this.Features.EnforceTvBeforeRadioBeforeData = true; this.DataRoot.AddChannelList(new ChannelList(SignalSource.Antenna | SignalSource.Tv | SignalSource.Radio, "Antenna")); this.DataRoot.AddChannelList(new ChannelList(SignalSource.Cable | SignalSource.Tv | SignalSource.Radio, "Cable")); diff --git a/source/ChanSort/MainForm.cs b/source/ChanSort/MainForm.cs index f399f96..20f93f9 100644 --- a/source/ChanSort/MainForm.cs +++ b/source/ChanSort/MainForm.cs @@ -891,6 +891,8 @@ namespace ChanSort.Ui return; if (!this.PromptHandlingOfUnsortedChannels()) return; + if (this.currentTvSerializer.Features.EnforceTvBeforeRadioBeforeData) + this.Editor.EnforceTvBeforeRadioBeforeData(); this.SaveTvDataFile(); this.DataRoot.NeedsSaving = false; this.RefreshGrid(this.gviewLeft, this.gviewRight); @@ -1613,18 +1615,21 @@ namespace ChanSort.Ui } // add custom columns used in the current channel list - foreach (var field in this.CurrentChannelList.VisibleColumnFieldNames) + if (this.CurrentChannelList != null) { - if (!field.StartsWith("+")) - continue; - var col = gview.Columns[field]; - if (col != null) - continue; - col = gview.Columns.AddField(field); - col.Caption = field.Substring(1); - col.FieldName = field; - col.UnboundDataType = typeof(string); - col.VisibleIndex = visIndex++; + foreach (var field in this.CurrentChannelList.VisibleColumnFieldNames) + { + if (!field.StartsWith("+")) + continue; + var col = gview.Columns[field]; + if (col != null) + continue; + col = gview.Columns.AddField(field); + col.Caption = field.Substring(1); + col.FieldName = field; + col.UnboundDataType = typeof(string); + col.VisibleIndex = visIndex++; + } } --this.ignoreEvents; diff --git a/source/Test.Api/EditorTest.cs b/source/Test.Api/EditorTest.cs new file mode 100644 index 0000000..72803fd --- /dev/null +++ b/source/Test.Api/EditorTest.cs @@ -0,0 +1,47 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Linq; +using ChanSort.Api; + +namespace Test.Api; + +[TestClass] +public class EditorTest +{ + [TestMethod] + public void TestEnforceTvBeforeRadioBeforeData() + { + var list = new ChannelList(SignalSource.All, "All"); + list.AddChannel(new ChannelInfo(SignalSource.Tv, 0, 1, "")); + list.AddChannel(new ChannelInfo(SignalSource.Tv, 1, 2, "")); + list.AddChannel(new ChannelInfo(SignalSource.Data, 2, 3, "")); + list.AddChannel(new ChannelInfo(SignalSource.Tv, 3, 4, "")); + list.AddChannel(new ChannelInfo(SignalSource.Radio, 4, 5, "")); + list.AddChannel(new ChannelInfo(SignalSource.Tv, 5, 6, "")); + list.AddChannel(new ChannelInfo(SignalSource.Radio, 6, 7, "")); + list.AddChannel(new ChannelInfo(SignalSource.Tv, 7, 8, "")); + list.AddChannel(new ChannelInfo(SignalSource.Data, 8, 9, "")); + list.AddChannel(new ChannelInfo(SignalSource.Data, 9, 10, "")); + list.AddChannel(new ChannelInfo(SignalSource.Radio, 10, 11, "")); + list.AddChannel(new ChannelInfo(SignalSource.Tv, 11, 12, "")); + + var ser = new CsvRefListSerializer("foo.csv"); + var dataRoot = new DataRoot(ser); + dataRoot.AddChannelList(list); + dataRoot.ApplyCurrentProgramNumbers(); + + var editor = new Editor(); + editor.DataRoot = dataRoot; + Assert.IsTrue(editor.EnforceTvBeforeRadioBeforeData()); + + var expected = new[] { 0, 1, 3, 5, 7, 11, 4, 6, 10, 2, 8, 9 }; + var newOrder = list.Channels.OrderBy(ch => ch.NewProgramNr).ToList(); + for (int i = 0; i net48 false + latest diff --git a/source/changelog.md b/source/changelog.md index 71689a0..00c2a98 100644 --- a/source/changelog.md +++ b/source/changelog.md @@ -1,6 +1,10 @@ ChanSort Change Log =================== +2023-10-28 +- improved tv.db/idtvChannel.bin support (e.g. Panasonic LSW500, LXW700) +- fixed error when changing "Auto hide/unhide columns" option while no list is loaded + 2023-10-22 - fixed loading .txt reference lists - added support for HB\_DATABASE\_\*.DBM channel lists with file size 74303