diff --git a/source/ChanSort.Api/Controller/Editor.cs b/source/ChanSort.Api/Controller/Editor.cs index 4fa1dd2..1654769 100644 --- a/source/ChanSort.Api/Controller/Editor.cs +++ b/source/ChanSort.Api/Controller/Editor.cs @@ -364,9 +364,12 @@ namespace ChanSort.Api if (appChannel.NewProgramNr == -1) { if (mode == UnsortedChannelMode.MarkDeleted) - continue; - appChannel.Hidden = true; - appChannel.Skip = true; + appChannel.IsDeleted = true; + else + { + appChannel.Hidden = true; + appChannel.Skip = true; + } } int progNr = GetNewPogramNr(appChannel, ref maxProgNr); @@ -381,7 +384,7 @@ namespace ChanSort.Api { // explicitly sorted if (channel.GetPosition(this.SubListIndex) != -1) - return channel.GetPosition(this.SubListIndex).ToString("d4"); + return channel.GetPosition(this.SubListIndex).ToString("d5"); // eventually hide unsorted channels if (this.unsortedChannelMode == UnsortedChannelMode.MarkDeleted) @@ -389,7 +392,7 @@ namespace ChanSort.Api // eventually append in old order if (this.unsortedChannelMode == UnsortedChannelMode.AppendInOrder) - return "B" + channel.OldProgramNr.ToString("d4"); + return "B" + channel.OldProgramNr.ToString("d5"); // sort alphabetically, with "." and "" on the bottom if (channel.Name == ".") @@ -409,10 +412,7 @@ namespace ChanSort.Api if (prNr > maxPrNr) maxPrNr = prNr; if (prNr == -1) - { - if (appChannel.OldProgramNr != -1 && this.unsortedChannelMode != UnsortedChannelMode.MarkDeleted) - prNr = ++maxPrNr; - } + prNr = ++maxPrNr; return prNr; } diff --git a/source/ChanSort.Api/Controller/SerializerBase.cs b/source/ChanSort.Api/Controller/SerializerBase.cs index bb0eb4c..94c87ac 100644 --- a/source/ChanSort.Api/Controller/SerializerBase.cs +++ b/source/ChanSort.Api/Controller/SerializerBase.cs @@ -65,6 +65,7 @@ namespace ChanSort.Api int deleted = 0; int hidden = 0; int skipped = 0; + int locked = 0; foreach (var channel in list.Channels) { if (channel.IsDeleted) @@ -73,10 +74,13 @@ namespace ChanSort.Api ++hidden; if (channel.Skip) ++skipped; + if (channel.Lock) + ++locked; } sb.Append("number of deleted channels: ").AppendLine(deleted.ToString()); sb.Append("number of hidden channels: ").AppendLine(hidden.ToString()); sb.Append("number of skipped channels: ").AppendLine(skipped.ToString()); + sb.Append("number of locked channels: ").AppendLine(locked.ToString()); sb.AppendLine(); } return sb.ToString(); diff --git a/source/ChanSort.Api/Model/DataRoot.cs b/source/ChanSort.Api/Model/DataRoot.cs index 025035a..436ebef 100644 --- a/source/ChanSort.Api/Model/DataRoot.cs +++ b/source/ChanSort.Api/Model/DataRoot.cs @@ -119,7 +119,29 @@ namespace ChanSort.Api foreach (var channel in list.Channels) { for (int i=0; i<=c; i++) - channel.SetPosition(i, channel.GetOldPosition(i)); + channel.SetPosition(i, channel.IsDeleted ? -1 : channel.GetOldPosition(i)); + } + } + } + #endregion + + #region SetPrNrForDeletedChannels() + public void SetPrNrForDeletedChannels() + { + // make sure that deleted channels have OldProgramNr = -1 + foreach (var list in this.ChannelLists) + { + if (list.IsMixedSourceFavoritesList) + continue; + foreach (var chan in list.Channels) + { + if (chan.IsDeleted) + { + chan.NewProgramNr = -1; + chan.OldProgramNr = -1; + } + else if (chan.OldProgramNr == -1) // old versions of ChanSort saved -1 and without setting IsDeleted + chan.IsDeleted = true; } } } diff --git a/source/ChanSort.Loader.GlobalClone/GcChannel.cs b/source/ChanSort.Loader.GlobalClone/GcChannel.cs index a438794..14ccdc1 100644 --- a/source/ChanSort.Loader.GlobalClone/GcChannel.cs +++ b/source/ChanSort.Loader.GlobalClone/GcChannel.cs @@ -7,6 +7,7 @@ namespace ChanSort.Loader.GlobalClone { internal int Index; internal XmlNode XmlNode; + internal bool IsDisabled; #region ctor() internal GcChannel(SignalSource source, int index, XmlNode node) diff --git a/source/ChanSort.Loader.GlobalClone/GcSerializer.cs b/source/ChanSort.Loader.GlobalClone/GcSerializer.cs index 878d09a..d1beffa 100644 --- a/source/ChanSort.Loader.GlobalClone/GcSerializer.cs +++ b/source/ChanSort.Loader.GlobalClone/GcSerializer.cs @@ -217,7 +217,7 @@ namespace ChanSort.Loader.GlobalClone #endregion #region ParseChannelInfoNode() - private void ParseChannelInfoNodes(XmlNode itemNode, ChannelInfo ch, bool onlyNames = false) + private void ParseChannelInfoNodes(XmlNode itemNode, GcChannel ch, bool onlyNames = false) { bool hasHexName = false; int mapType = 0; @@ -230,7 +230,9 @@ namespace ChanSort.Loader.GlobalClone { // common to ATV and DTV case "prNum": - ch.OldProgramNr = int.Parse(info.InnerText) & 0x3FFF; + ch.OldProgramNr = int.Parse(info.InnerText); + if (ch.OldProgramNr != -1) // older versions of ChanSort accidentally saved -1 instead of IsDeleted=1 + ch.OldProgramNr &= 0x3FFF; break; case "vchName": // In old file format versions, this field contains binary data stuffed into UTF8 envelopes. that data is correct @@ -292,6 +294,9 @@ namespace ChanSort.Loader.GlobalClone // ? break; case "isDisabled": + ch.IsDisabled = int.Parse(info.InnerText) != 0; + break; + case "isDeleted": ch.IsDeleted = int.Parse(info.InnerText) != 0; break; case "usSatelliteHandle": @@ -366,6 +371,7 @@ namespace ChanSort.Loader.GlobalClone { foreach (var list in this.DataRoot.ChannelLists) { + foreach (var channel in list.Channels) { var ch = channel as GcChannel; @@ -411,6 +417,8 @@ namespace ChanSort.Loader.GlobalClone // ? break; case "isDisabled": + node.InnerText = ch.IsDeleted || ch.IsDisabled ? "1" : "0"; + break; case "isDeleted": node.InnerText = ch.IsDeleted ? "1" : "0"; break; @@ -475,11 +483,13 @@ namespace ChanSort.Loader.GlobalClone { foreach (var list in this.DataRoot.ChannelLists) { + if (list.IsMixedSourceFavoritesList) + continue; foreach (var channel in list.Channels) { var gcChannel = channel as GcChannel; if (gcChannel != null) - this.ParseChannelInfoNodes(gcChannel.XmlNode, channel, true); + this.ParseChannelInfoNodes(gcChannel.XmlNode, gcChannel, true); } } } diff --git a/source/ChanSort/MainForm.cs b/source/ChanSort/MainForm.cs index 254172b..ddbd6f7 100644 --- a/source/ChanSort/MainForm.cs +++ b/source/ChanSort/MainForm.cs @@ -526,10 +526,11 @@ namespace ChanSort.Ui if (!this.PromptSaveAndContinue()) return false; + serializer.DataRoot.SetPrNrForDeletedChannels(); this.SetFileName(tvDataFile); this.currentPlugin = plugin; this.currentTvSerializer = serializer; - this.DataRoot = this.currentTvSerializer.DataRoot; + this.DataRoot = serializer.DataRoot; this.AddFileToMruList(this.currentTvFile); this.UpdateMruMenu(); @@ -769,32 +770,37 @@ namespace ChanSort.Ui { foreach (var channel in list.Channels) { - if (channel.NewProgramNr < 0 && channel.OldProgramNr >= 0) + if (channel.NewProgramNr < 0 && !channel.IsDeleted) { hasUnsorted = true; break; } } } - if (!hasUnsorted) - return true; - var msg = Resources.MainForm_PromptHandlingOfUnsortedChannels_Question; - DialogResult res; - using (var dlg = new ActionBoxDialog(msg)) + UnsortedChannelMode mode = UnsortedChannelMode.MarkDeleted; + + if (hasUnsorted) { - dlg.AddAction(Resources.MainForm_PromptHandlingOfUnsortedChannels_Append, DialogResult.Yes, dlg.FullList); - if (this.currentTvSerializer.Features.CanDeleteChannels) - dlg.AddAction(Resources.MainForm_PromptHandlingOfUnsortedChannels_Delete, DialogResult.No, dlg.Delete); - dlg.AddAction(Resources.MainForm_Cancel, DialogResult.Cancel, dlg.Cancel); - res = dlg.ShowDialog(this); + var msg = Resources.MainForm_PromptHandlingOfUnsortedChannels_Question; + DialogResult res; + using (var dlg = new ActionBoxDialog(msg)) + { + dlg.AddAction(Resources.MainForm_PromptHandlingOfUnsortedChannels_Append, DialogResult.Yes, dlg.FullList); + if (this.currentTvSerializer.Features.CanDeleteChannels) + dlg.AddAction(Resources.MainForm_PromptHandlingOfUnsortedChannels_Delete, DialogResult.No, dlg.Delete); + dlg.AddAction(Resources.MainForm_Cancel, DialogResult.Cancel, dlg.Cancel); + res = dlg.ShowDialog(this); + } + + if (res == DialogResult.Cancel) + return false; + if (res == DialogResult.Yes) + mode = UnsortedChannelMode.AppendInOrder; } - if (res == DialogResult.Cancel) - return false; - - this.Editor.AutoNumberingForUnassignedChannels( - res == DialogResult.Yes ? UnsortedChannelMode.AppendInOrder : UnsortedChannelMode.MarkDeleted); + // ensure unsorted and deleted channels have a valid program number + this.Editor.AutoNumberingForUnassignedChannels(mode); return true; } @@ -903,6 +909,8 @@ namespace ChanSort.Ui { foreach (var chan in list.Channels) { + if (chan.IsDeleted) // during the saving process, deleted channels temporarily got a NewProgramNr assigned + chan.NewProgramNr = -1; chan.OldProgramNr = chan.NewProgramNr; chan.OldFavIndex.Clear(); chan.OldFavIndex.AddRange(chan.FavIndex); @@ -1774,7 +1782,7 @@ namespace ChanSort.Ui { foreach (var channel in list.Channels.OrderBy(c => c.NewProgramNr)) { - if (channel.IsDeleted || channel.OldProgramNr == -1) + if (channel.IsDeleted || channel.NewProgramNr == -1) continue; sb.Append(list.ShortCaption).Append(sep); sb.Append(channel.NewProgramNr).Append(sep); diff --git a/source/changelog.md b/source/changelog.md index 5848221..fe7ece3 100644 --- a/source/changelog.md +++ b/source/changelog.md @@ -1,10 +1,13 @@ ChanSort Change Log =================== +2017-11-30 +- fixed: deleting channels and selecting to "Remove unsorted channels" + when saving could produce problems loading the list on the TV. + i.e. LG GlobalClone.TLL 2017-11-13 - Samsung .zip: fixed loading/saving of favorites A-E - 2017-10-29 - Show popup with download link for MS Visual C++ 2010 x86 Redist (this package is needed to open lists with a SQLite file format)