diff --git a/source/ChanSort.Api/Controller/Editor.cs b/source/ChanSort.Api/Controller/Editor.cs
index 47f6ad4..399561a 100644
--- a/source/ChanSort.Api/Controller/Editor.cs
+++ b/source/ChanSort.Api/Controller/Editor.cs
@@ -415,8 +415,8 @@ namespace ChanSort.Api
///
private void ApplyPrNrToFavLists(ChannelInfo tvChannel)
{
- var supMask = (int)this.DataRoot.SupportedFavorites;
- var refMask = (int)tvChannel.Favorites;
+ var supMask = (ulong)this.DataRoot.SupportedFavorites;
+ var refMask = (ulong)tvChannel.Favorites;
for (int i = 0; supMask != 0; i++)
{
tvChannel.FavIndex[i] = (refMask & 0x01) == 0 ? -1 : tvChannel.NewProgramNr;
diff --git a/source/ChanSort.Api/Model/DataRoot.cs b/source/ChanSort.Api/Model/DataRoot.cs
index bab56d7..bf1a027 100644
--- a/source/ChanSort.Api/Model/DataRoot.cs
+++ b/source/ChanSort.Api/Model/DataRoot.cs
@@ -267,6 +267,8 @@ namespace ChanSort.Api
public string GetFavListCaption(int favIndex, bool asTabCaption = false)
{
+ if (favIndex < 0)
+ return "";
var hasCaption = favListCaptions.TryGetValue(favIndex, out var caption);
if (!asTabCaption)
return caption;
diff --git a/source/ChanSort.Loader.Enigma2/Enigma2Plugin.cs b/source/ChanSort.Loader.Enigma2/Enigma2Plugin.cs
index 3472fa0..6a87622 100644
--- a/source/ChanSort.Loader.Enigma2/Enigma2Plugin.cs
+++ b/source/ChanSort.Loader.Enigma2/Enigma2Plugin.cs
@@ -6,7 +6,7 @@ namespace ChanSort.Loader.Enigma2
{
public string DllName { get; set; }
public string PluginName => "Enigma2 (Linux Receiver)";
- public string FileFilter => "bouquets.*";
+ public string FileFilter => "lamedb";
public SerializerBase CreateSerializer(string inputFile)
{
diff --git a/source/ChanSort.Loader.Enigma2/Serializer.cs b/source/ChanSort.Loader.Enigma2/Serializer.cs
index 2d1d504..c6abbc0 100644
--- a/source/ChanSort.Loader.Enigma2/Serializer.cs
+++ b/source/ChanSort.Loader.Enigma2/Serializer.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
using ChanSort.Api;
namespace ChanSort.Loader.Enigma2
@@ -17,8 +18,7 @@ namespace ChanSort.Loader.Enigma2
{
private static readonly Encoding utf8WithoutBom = new UTF8Encoding(false);
- private ChannelList tv = new ChannelList(SignalSource.Digital | SignalSource.Tv, "TV");
- private ChannelList radio = new ChannelList(SignalSource.Digital | SignalSource.Radio, "Radio");
+ private ChannelList channels = new ChannelList(SignalSource.Digital, "All Channels");
private readonly List favListFileNames = new();
private readonly Dictionary transponderByLamedbId = new();
@@ -43,10 +43,8 @@ namespace ChanSort.Loader.Enigma2
this.Features.SupportedFavorites = 0; // dynamically added
this.Features.CanSaveAs = false;
- this.tv.IsMixedSourceFavoritesList = true;
- this.DataRoot.AddChannelList(this.tv);
- this.radio.IsMixedSourceFavoritesList = true;
- this.DataRoot.AddChannelList(this.radio);
+ this.channels.IsMixedSourceFavoritesList = true;
+ this.DataRoot.AddChannelList(this.channels);
// hide columns for fields that don't exist in Silva-Schneider channel list
foreach (var list in this.DataRoot.ChannelLists)
@@ -73,11 +71,28 @@ namespace ChanSort.Loader.Enigma2
this.decoder = new DvbStringDecoder(this.DefaultEncoding);
this.LoadLamedb();
- int favId = 0;
- foreach(var file in Directory.GetFiles(Path.GetDirectoryName(this.FileName), "userbouquet.*"))
- this.LoadBouquet(file, ref favId);
- }
+ int favIndex = 0;
+ // load all userbouquet files listed in bouquets.tv
+ var path = Path.Combine(Path.GetDirectoryName(this.FileName), "bouquets.tv");
+ if (File.Exists(path))
+ LoadBouquets(path, ref favIndex);
+
+ // load all userbouquet files listed in bouquets.radio
+ path = Path.Combine(Path.GetDirectoryName(this.FileName), "bouquets.radio");
+ if (File.Exists(path))
+ LoadBouquets(path, ref favIndex);
+
+ // load all unlisted userbouquet files
+ foreach (var file in Directory.GetFiles(Path.GetDirectoryName(this.FileName), "userbouquet.*"))
+ {
+ var ext = Path.GetExtension(file);
+ if (ext != ".tv" && ext != ".radio") // ignore .del, .bak and other irrelevant files
+ continue;
+ if (!this.favListFileNames.Contains(file))
+ this.LoadUserBouquet(file, ref favIndex);
+ }
+ }
#endregion
#region LoadLamedb()
@@ -213,20 +228,33 @@ namespace ChanSort.Loader.Enigma2
}
}
- this.DataRoot.AddChannel(this.tv, ch);
+ //var list = (ch.SignalSource & SignalSource.Radio) != 0 ? this.radio : this.tv;
+ var list = this.channels;
+ this.DataRoot.AddChannel(list, ch);
this.channelsByBouquetId[$"{ch.DvbNamespace}:{ch.OriginalNetworkId}:{ch.TransportStreamId}:{ch.ServiceId}"] = ch;
}
#endregion
- #region LoadBoquet
- private void LoadBouquet(string file, ref int favIndex)
+ #region LoadBouquets
+ private void LoadBouquets(string file, ref int favIndex)
{
- ChannelList list;
- if (file.EndsWith(".tv"))
- list = this.tv;
- else if (file.EndsWith(".radio"))
- list = this.radio;
- else
+ var regex = new Regex(".*FROM BOUQUET \"(.*?)\".*");
+ foreach (var line in File.ReadAllLines(file))
+ {
+ var match = regex.Match(line);
+ if (match.Success)
+ {
+ var path = Path.Combine(Path.GetDirectoryName(file), match.Groups[1].Value);
+ LoadUserBouquet(path, ref favIndex);
+ }
+ }
+ }
+ #endregion
+
+ #region LoadUserBoquet
+ private void LoadUserBouquet(string file, ref int favIndex)
+ {
+ if (!File.Exists(file))
return;
using var r = new StreamReader(File.OpenRead(file), utf8WithoutBom);
@@ -238,7 +266,6 @@ namespace ChanSort.Loader.Enigma2
}
this.DataRoot.SetFavListCaption(favIndex, line.Substring(6));
- this.Features.SupportedFavorites = (Favorites)((int)this.Features.SupportedFavorites<<1)|Favorites.A;
int lineNr = 0;
int progNr = 0;
@@ -289,7 +316,9 @@ namespace ChanSort.Loader.Enigma2
ch.SetOldPosition(1+favIndex, ++progNr);
}
+
this.favListFileNames.Add(file);
+ this.Features.SupportedFavorites = (Favorites)((ulong)this.Features.SupportedFavorites << 1) | Favorites.A;
++favIndex;
}
#endregion
@@ -338,7 +367,7 @@ namespace ChanSort.Loader.Enigma2
var file = this.favListFileNames[favIndex];
using var w = new StreamWriter(File.OpenWrite(file), utf8WithoutBom);
w.WriteLine($"#NAME {this.DataRoot.GetFavListCaption(favIndex)}");
- foreach (var ch in this.tv.Channels.OrderBy(c => c.GetPosition(favIndex+1)))
+ foreach (var ch in this.channels.Channels.OrderBy(c => c.GetPosition(favIndex+1)))
{
if (!(ch is Channel c) || c.GetPosition(favIndex + 1) < 0)
continue;
diff --git a/source/ChanSort/MainForm.cs b/source/ChanSort/MainForm.cs
index 2144fbc..be0f5d3 100644
--- a/source/ChanSort/MainForm.cs
+++ b/source/ChanSort/MainForm.cs
@@ -443,10 +443,12 @@ namespace ChanSort.Ui
this.repositoryItemCheckedComboBoxEdit2.Items.Clear();
var regex = "[";
var favCount = 0;
- for (var favMask = (uint)favorites; (favMask & 1) != 0; favMask >>= 1)
+ for (var favMask = (ulong)favorites; (favMask & 1) != 0; favMask >>= 1)
{
var c = (char) ('A' + favCount);
++favCount;
+ if (favCount >= 26)
+ continue;
this.repositoryItemCheckedComboBoxEdit1.Items.Add(c);
this.repositoryItemCheckedComboBoxEdit2.Items.Add(c);
@@ -467,13 +469,15 @@ namespace ChanSort.Ui
regex += "]*";
this.repositoryItemCheckedComboBoxEdit1.Mask.EditMask = regex;
this.repositoryItemCheckedComboBoxEdit2.Mask.EditMask = regex;
-
+
+ this.tabSubList.BeginUpdate();
while (this.tabSubList.TabPages.Count > favCount + 1)
this.tabSubList.TabPages.RemoveAt(this.tabSubList.TabPages.Count - 1);
while (this.tabSubList.TabPages.Count < favCount + 1)
this.tabSubList.TabPages.Add();
for (int i = 1; i < this.tabSubList.TabPages.Count; i++)
this.tabSubList.TabPages[i].Text = this.DataRoot.GetFavListCaption(i - 1, true);
+ this.tabSubList.EndUpdate();
if (!this.DataRoot.SortedFavorites || this.subListIndex >= favCount)
{
@@ -1926,8 +1930,14 @@ namespace ChanSort.Ui
var sb = new StringBuilder();
int i = 0;
- for (var mask = (int)fav; mask != 0; mask >>= 1)
+ for (var mask = (ulong)fav; mask != 0; mask >>= 1)
{
+ if (i >= 26)
+ {
+ sb.Append("+");
+ break;
+ }
+
if ((mask & 1) != 0)
sb.Append((char)('A' + i));
++i;
diff --git a/source/ChanSort/Properties/licenses.licx b/source/ChanSort/Properties/licenses.licx
index 0f52b01..d1aab4d 100644
--- a/source/ChanSort/Properties/licenses.licx
+++ b/source/ChanSort/Properties/licenses.licx
@@ -1,5 +1,6 @@
-DevExpress.XtraEditors.PictureEdit, DevExpress.XtraEditors.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.ComboBoxEdit, DevExpress.XtraEditors.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraBars.BarManager, DevExpress.XtraBars.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.CheckEdit, DevExpress.XtraEditors.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.Repository.RepositoryItemTextEdit, DevExpress.XtraEditors.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
+DevExpress.XtraEditors.PictureEdit, DevExpress.XtraEditors.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
DevExpress.XtraEditors.ButtonEdit, DevExpress.XtraEditors.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
-DevExpress.XtraBars.BarManager, DevExpress.XtraBars.v20.1, Version=20.1.8.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a
diff --git a/source/ChanSort/ReferenceListForm.cs b/source/ChanSort/ReferenceListForm.cs
index 7158ec2..62dd364 100644
--- a/source/ChanSort/ReferenceListForm.cs
+++ b/source/ChanSort/ReferenceListForm.cs
@@ -18,16 +18,21 @@ namespace ChanSort.Ui
private SerializerBase serializer;
private readonly string[] closeButtonText;
- class MixedSourceList
+ class ListOption
{
+ private DataRoot root;
public ChannelList ChannelList { get; }
- public int FavIndex { get; }
+ public int PosIndex { get; }
- public MixedSourceList(ChannelList list, int favIndex)
+ public string Caption { get; }
+ public ListOption(ChannelList list, int posIndex, string caption)
{
ChannelList = list;
- FavIndex = favIndex;
+ PosIndex = posIndex;
+ Caption = caption;
}
+
+ public override string ToString() => Caption;
}
public ReferenceListForm(MainForm main)
@@ -129,21 +134,29 @@ namespace ChanSort.Ui
continue;
if (list.IsMixedSourceFavoritesList)
{
- this.comboSource.Properties.Items.Add(new MixedSourceList(list, i))
+ for (int i = 0; i <= list.FavListCount; i++)
+ this.comboSource.Properties.Items.Add(new ListOption(list, i, list + (i==0 ? "" : " - " + serializer.DataRoot.GetFavListCaption(i-1))));
}
else
- this.comboSource.Properties.Items.Add(list);
+ this.comboSource.Properties.Items.Add(new ListOption(list, 0, list.Caption));
}
this.comboTarget.EditValue = null;
this.comboTarget.Properties.Items.Clear();
foreach (var list in main.DataRoot.ChannelLists)
{
- if (!list.IsMixedSourceFavoritesList && list.Channels.Count > 0)
+ if (list.Channels.Count == 0)
+ continue;
+ if (list.IsMixedSourceFavoritesList)
{
- this.comboTarget.Properties.Items.Add(list);
+ for (int i = 0; i <= list.FavListCount; i++)
+ this.comboTarget.Properties.Items.Add(new ListOption(list, i, list + (i==0 ? "" : " - " + main.DataRoot.GetFavListCaption(i-1))));
+ }
+ else
+ {
+ this.comboTarget.Properties.Items.Add(new ListOption(list, 0, list.Caption));
if (main.CurrentChannelList == list)
- this.comboTarget.SelectedItem = list;
+ this.comboTarget.SelectedIndex = this.comboTarget.Properties.Items.Count-1;
}
}
@@ -178,9 +191,9 @@ namespace ChanSort.Ui
checkEdit.Checked = checkEdit.Enabled = true;
}
- var list = (ChannelList) this.comboSource.EditValue;
+ var list = (ListOption) this.comboSource.EditValue;
this.lblSourceInfo.Text = GetInfoText(list, true);
- list = (ChannelList) this.comboTarget.EditValue;
+ list = (ListOption) this.comboTarget.EditValue;
this.lblTargetInfo.Text = GetInfoText(list, false);
var canApply = (cbAnalog.Checked || cbDigital.Checked) && (cbTv.Checked || cbRadio.Checked || cbData.Checked);
@@ -191,8 +204,9 @@ namespace ChanSort.Ui
#region GetInfoText()
- private string GetInfoText(ChannelList list, bool source)
+ private string GetInfoText(ListOption option, bool source)
{
+ var list = option?.ChannelList;
var src = list?.SignalSource ?? 0;
var sb = new StringBuilder();
@@ -277,14 +291,14 @@ namespace ChanSort.Ui
UpdateInfoTextAndOptions();
// auto-select a compatible source list
- var list = (ChannelList)this.comboTarget.EditValue;
+ var list = ((ListOption)this.comboTarget.EditValue)?.ChannelList;
if (list != null)
{
this.comboSource.SelectedIndex = -1;
var src = list.SignalSource;
- foreach (ChannelList sourceList in this.comboSource.Properties.Items)
+ foreach (ListOption sourceList in this.comboSource.Properties.Items)
{
- if ((sourceList.SignalSource & src) == src)
+ if ((sourceList.ChannelList.SignalSource & src) == src)
{
this.comboSource.SelectedItem = sourceList;
break;
@@ -299,7 +313,7 @@ namespace ChanSort.Ui
private void comboSource_EditValueChanged(object sender, EventArgs e)
{
UpdateInfoTextAndOptions();
- var list = (ChannelList)this.comboSource.EditValue;
+ var list = ((ListOption)this.comboSource.EditValue)?.ChannelList;
this.comboPrNr.Text = list == null || list.Count == 0 ? "1" : list.Channels.Min(ch => Math.Max(ch.OldProgramNr, 1)).ToString();
}
@@ -309,14 +323,14 @@ namespace ChanSort.Ui
private void btnApply_Click(object sender, EventArgs e)
{
- var src = (ChannelList) this.comboSource.EditValue;
- var target = (ChannelList) this.comboTarget.EditValue;
+ var src = (ListOption) this.comboSource.EditValue;
+ var target = (ListOption) this.comboTarget.EditValue;
int offset;
if (int.TryParse(this.comboPrNr.Text, out offset))
- offset -= src.Channels.Min(ch => Math.Max(ch.OldProgramNr, 1));
+ offset -= src.ChannelList.Channels.Min(ch => Math.Max(ch.OldProgramNr, 1));
bool overwrite = true;
- if (target.GetChannelsByNewOrder().Any(ch => ch.NewProgramNr != -1))
+ if (target.ChannelList.GetChannelsByNewOrder().Any(ch => ch.NewProgramNr != -1))
{
using (var dlg = new ActionBoxDialog(Resources.ReferenceListForm_btnApply_ConflictHandling))
{
@@ -327,7 +341,7 @@ namespace ChanSort.Ui
switch (dlg.ShowDialog(this))
{
case DialogResult.OK:
- target.Channels.ForEach(ch => ch.NewProgramNr = -1);
+ target.ChannelList.Channels.ForEach(ch => ch.NewProgramNr = -1);
break;
case DialogResult.Yes:
//overwrite = true;
@@ -341,7 +355,7 @@ namespace ChanSort.Ui
}
}
- main.Editor.ApplyReferenceList(this.serializer.DataRoot, src, target, false, offset, FilterChannel, overwrite, this.cbConsecutive.Checked);
+ main.Editor.ApplyReferenceList(this.serializer.DataRoot, src.ChannelList, target.ChannelList, false, offset, FilterChannel, overwrite, this.cbConsecutive.Checked);
main.RefreshGrids();
}