- specific .ini settings for various Philips ChannelMap_xxx versions and sub-variants for version 100

- lots of documentation around Philips lists
- working configuration for ChannelMap_100 variant with cmdb files (redordering confirmed, hide/lock/rename/favorites are best-effort)
- pressing the "Del"-key on the keyboard no longer deletes a channel when a text editor is open
- dragging a file (or something else) from outside ChanSort over the ChanSort window no longer creates an error
- opening a file containing a read-only channel list now shows the original numbers
This commit is contained in:
Horst Beham
2021-09-04 14:24:41 +02:00
parent 74e42f70de
commit c2073534fc
8 changed files with 477 additions and 323 deletions

View File

@@ -1,4 +1,8 @@
# [dtv_chmdb_x.bin:filesize] defines the overall layout of the file
# This file holds the definitions for various verions of the binary "dtv_cmdb_2.bin" channel list format used by some models of Sharp, Toshiba, Dyon, OK. and others
# Some files have an 8 byte header starting with "0004", others have an 12 byte header starting with "0005"
# [dtv_chmdb_x.bin:filesize] defines the overall layout of the various file format versions. Values for x are 0=antenna, 1=cable, 2=satellite
# lenChannelRecord, lenTransponderRecord and lenSatelliteRecord are then used to select the [dvsChannel:...], [dvbsTransponder:...] and [dvbsSatellite:...] sections
# Rabinowitsch - dtv_cmd_2.bin with 1296 KB
@@ -40,7 +44,7 @@ offDebug=10
lenDebug=5
# Liwest 0005 with 1296 KB
# Liwest Thoshiba files with 1296 KB. These have an 8 byte header with 0005 and shift all other data back by 4
[dtv_cmdb_2.bin:1326669]
offChannelBitmap=12
@@ -61,7 +65,7 @@ numSatelliteRecord=254
# overice Toshiba - dtv_cmdb_2.bin with 1322 KB
# overice Toshiba - dtv_cmdb_2.bin with 1322 KB and a "0005" header
[dtv_cmdb_2.bin:1353209]
offChannelBitmap=12
@@ -106,8 +110,6 @@ offServiceId=34
offAudioPid=52
offName=144
lenName=50
#offProvider=0
#lenProvider=0
# SetEdit Toshiba - dtv_cmdb_2.bin with 1684 KB

View File

@@ -1,4 +1,39 @@
# 1.x format
############################################################################
# Repair\CM_*_LA_CK.BIN file (or similar) with a hidden .xml - stable
[Repair_xml]
reorderRecordsByChannelNumber=false
############################################################################
# Repair\channel_db_ver.db, atv_chan_phy_c.db, FLASH_DTVINFO_S_FTA, mgr_chan_s_fta.db, ... - experimental
# unfortunately read-only because all attempts so far produced inconsistencies between the channels in the menu and what the tuner actually put on screen
[mgr_chan_s_fta.db]
lenHeader=64
lenEntry=476
lenFooter=12
offFooterChecksum=8
reorderRecordsByChannelNumber=false
allowEdit=false
[mgr_chan_s_fta.db_entry]
# there is a program number at offset 0 and 452. My guess is that 0 is the "new" number and 452 the "old" number, which should be left untouched. Or it is the other way around.
# when both numbers are updated and also the value at 456 set to PrNr-1, the TV didn't show any changes.
offProgNr=0
offName=20
offFav=16
lenName=200
offFreq=444,468
offSymbolRate=450
offRecordIndex=456
offTsid=460
offSid=464
offOnid=466
############################################################################
# Repair\ChannelList\chanLst.bin version 1.x with AntennaDigSrvTable, CableDigSrvTable and service.dat (for DVB-S) - should be stable
[service.dat_entry]
offPcrPid=0
@@ -45,7 +80,26 @@ offChecksum=0
offSymbolRate=8
offFreq=18
# ChannelMap_45 format (also used for ChannelMap_30)
############################################################################
# PhilipsChannelMaps\ChannelMap_11 with AntennaDigSrvTable, CableDigSrvTable, SatelliteDigSrvTable and service.dat - not supported
############################################################################
# ChannelMap_30 with list.db, tv.db, CableChannelMaps.db, CableDb.bin, TerrestrialChannelMaps.db, TerrestrialDb.bin, SatelliteChannelMaps.db, SatelliteDb.bin - experimental
# uses the [Map45_...] mappings for the *Db.bin files
[Map30]
incrementFavListVersion=false
reorderRecordsByChannelNumber=false
############################################################################
# ChannelMap_45 with list.db, tv.db, HsvDvbCSettings, CableDb.bin, HsvDvbTSettings.bin, TerrestrialDb.bin, SatelliteDb.bin - experimental
[Map45]
incrementFavListVersion=false
reorderRecordsByChannelNumber=false
[Map45_CableDb.bin_entry]
offId=0
@@ -89,57 +143,67 @@ offUnk1=48
offUnk2=68
offPolarity=72
[Map30]
incrementFavListVersion=true
[Map45]
incrementFavListVersion=true
############################################################################
# ChannelMap_100 with DVBC.xml, DVBT.xml, DVBS.xml, DVBSall.xml
# This format has different variants without a unique sub-version number:
# 1) with a channelFile.bin, no indentation, uppercase hex digits, padded names, no "Scramble" attribute
# 2) without .bin files, no indentation, uppercase hex digits, padded names, a "Scramble" attribute
# 3) with additional *tv_cmdb*.bin files, indentation in XML, lowercase hex digits, unpadded names, a "Scramble" attribute and requirement to keep record order between .xml and .bin in-sync. Often with a "Clone" folder. - stable
[Map100]
# setFavoriteNumber: true|false; if false, the FavoriteNumber attribute won't be changed
setFavoriteNumber=true
#setReorderedFavNumber: true|false; if true, favorites can be in a different order than the main program numbers; default: false
setReorderedFavNumber=true
# reorderRecordsByChannelNumber: true|false; defines whether the element lines in the XML file are reordered by their ChannelNumber or kept at their location; default: false
reorderRecordsByChannelNumber=true
# padChannelName: true|false; if true, fill the hex-encoded channel name with 0x00 0x00 to maintain a fixed length; default: true
padChannelName=true
# allowDelete: true|false; if true, channels can be removed from the .xml. This breaks channel lists that contain .bin files that must be kept in-sync; default: false
allowDelete=true
#setReorderedFavNumber: true to allow favorite numbers in a different order than the main program number; false to enforce same order; default: false
setReorderedFavNumber=false
# settings for the ChannelMap_100 variant that includes a channelFile.bin file
[Map100_channelFile.bin]
setFavoriteNumber=true
setReorderedFavNumber=true
reorderRecordsByChannelNumber=false
padChannelName=true
allowDelete=false
# settings for the ChannelMap_100 variant that includes an atv_cmdb.bin file
[Map100_cmdb.bin]
setFavoriteNumber=true
setReorderedFavNumber=true
reorderRecordsByChannelNumber=false
padChannelName=false
allowDelete=false
############################################################################
# ChannelMap_105: channelFile.bin, Favorite.xml, *.txt, *.xml.
# No XML indentation, added <SatelliteListcopy> element, uppercase hex, padded names, "Scrambled" attribute (with a "d" at the end)
[Map105]
incrementFavListVersion=true
setFavoriteNumber=false
satelliteListcopy=remove
[Map110]
# satelliteListcopy: true|false|remove|(empty); when empty the original value is kept as-is; "remove" removes the XML element; default: empty
satelliteListcopy=remove
# reorderXmlNodesByChannelNumber: true|false; defines whether the element lines in the XML file are reordered by their ChannelNumber or kept at their location; default: true
reorderXmlNodesByChannelNumber=true
# setFavoriteNumber: true|false; if false (default), the FavoriteNumber attribute will always be 0 in format 105,110 and the actual number is defined in the Favorite.xml file; default: false
setFavoriteNumber=false
# userReorderChannel: 0|1|remove|(blank); when blank the original value is kept as-is, "remove" removes the attribute, 0 and 1 are written as literals; default: 0
userReorderChannel=0
setReorderedFavNumber=false
reorderRecordsByChannelNumber=false
# incrementFavListVersion: true|false; when true the Version attribute in the Favorite.xml file gets incremented every time the file is saved; default: false
incrementFavListVersion=false
allowDelete=false
############################################################################
# ChannelMap_110: same as 105 with an additional "UserReorderChannel" attribute (which should probably left unchanged, even after reordering)
# Format with Repair\ folder containing channel_db_ver.db, atv_chan_phy_c.db, FLASH_DTVINFO_S_FTA, mgr_chan_s_fta.db, ...
[mgr_chan_s_fta.db]
lenHeader=64
lenEntry=476
lenFooter=12
offFooterChecksum=8
[mgr_chan_s_fta.db_entry]
offProgNr=0,452
offName=20
offFav=16
lenName=200
offFreq=444,468
offSymbolRate=450
offPrevProgNr=456
offTsid=460
offSid=464
offOnid=466
[Map110]
satelliteListcopy=remove
setFavoriteNumber=false
setReorderedFavNumber=false
# userReorderChannel: 0|1|remove|(blank); when blank the original value is kept as-is, "remove" removes the attribute, 0 and 1 are written as literals; default: 0
userReorderChannel=0
reorderRecordsByChannelNumber=false
incrementFavListVersion=false
allowDelete=false

View File

@@ -47,7 +47,9 @@ namespace ChanSort.Loader.Philips
nameof(Channel.OriginalNetworkId),
nameof(Channel.ServiceId)
};
dvbsChannels.ReadOnly = true;
var sec = ini.GetSection("mgr_chan_s_fta.db");
dvbsChannels.ReadOnly = sec.GetBool("allowEdit", false);
}
#region Load()
@@ -168,37 +170,42 @@ namespace ChanSort.Loader.Philips
var offFooterChecksum = sec.GetInt("offFooterChecksum");
var mapping = new DataMapping(ini.GetSection("mgr_chan_s_fta.db_entry"));
#if JUST_CHANGE_NUMBERS
// update channel data
foreach (var ch in dvbsChannels.Channels)
{
mapping.SetDataPtr(data, lenHeader + ch.RecordOrder * lenEntry);
mapping.SetWord("offProgNr", ch.NewProgramNr);
mapping.SetWord("offPrevProgNr", ch.NewProgramNr - 1);
mapping.SetWord("offFav", Math.Max(0, ch.GetPosition(1)));
}
#else
// physically reorder channels
var newData = new byte[data.Length];
Array.Copy(data, newData, lenHeader);
var off = lenHeader + lenEntry * dvbsChannels.Channels.Count;
Array.Copy(data, off, newData, off, lenFooter);
int i = 0;
foreach (var ch in dvbsChannels.Channels.OrderBy(c => c.NewProgramNr))
if (sec.GetBool("reorderRecordsByChannelNumber"))
{
off = lenHeader + i * lenEntry;
Array.Copy(data, lenHeader + ch.RecordOrder * lenEntry, newData, off, lenEntry);
mapping.SetDataPtr(newData, off);
mapping.SetWord("offProgNr", ch.NewProgramNr);
mapping.SetWord("offPrevProgNr", ch.NewProgramNr - 1);
mapping.SetWord("offFav", Math.Max(0, ch.GetPosition(1)));
ch.RecordOrder = i;
++i;
// physically reorder channels
var newData = new byte[data.Length];
Array.Copy(data, newData, lenHeader);
var off = lenHeader + lenEntry * dvbsChannels.Channels.Count;
Array.Copy(data, off, newData, off, lenFooter);
int i = 0;
foreach (var ch in dvbsChannels.Channels.OrderBy(c => c.NewProgramNr))
{
off = lenHeader + i * lenEntry;
Array.Copy(data, lenHeader + ch.RecordOrder * lenEntry, newData, off, lenEntry);
mapping.SetDataPtr(newData, off);
mapping.SetWord("offProgNr", ch.NewProgramNr);
//mapping.SetWord("offPrevProgNr", ch.NewProgramNr - 1);
mapping.SetWord("offFav", Math.Max(0, ch.GetPosition(1)));
ch.RecordOrder = i;
++i;
}
data = newData;
}
else
{
// update channel data
foreach (var ch in dvbsChannels.Channels)
{
mapping.SetDataPtr(data, lenHeader + ch.RecordOrder * lenEntry);
mapping.SetWord("offProgNr", ch.NewProgramNr);
//mapping.SetWord("offPrevProgNr", ch.NewProgramNr - 1);
mapping.SetWord("offFav", Math.Max(0, ch.GetPosition(1)));
}
}
data = newData;
#endif
// update checksum
var offChecksum = data.Length - lenFooter + offFooterChecksum;
var checksum = CalcChecksum(data, 0, offChecksum);

View File

@@ -34,12 +34,17 @@ namespace ChanSort.Loader.Philips
The Philips editor updates the checksums in chanLst.bin (but that file does not include the DVBS.xml file, only DVBT.xml, DVBC.xml an DVBSall.xml)
The ChannelMap_100 formats can also be edited with Onka editor. Unlike the Philips editor, this one sorts the XML nodes by their new ChannelNumber.
Onka can also read/write formats 105 and 110, but removes all XML attributes that it doesn't know (and didn't exist in 100), like "Scrambled" and "UserReorderChannel".
It adds an XML namespace, indentation and uses short closing tags and removes the <SatelliteListcopy> element from format 105/110.
Onka does not update chanLst.bin (which isn't required when only DVBS.xml is modified)
Nevertheless a user reported that swapping DVB-S channels 1 and 2 with Onka on a TV that uses format 110 worked for him.
Onka can also read/write formats 105 and 110, but removes all XML attributes that it doesn't know (and didn't exist in 100), like "Scramble"/"Scrambled" and "UserReorderChannel".
It adds an XML namespace, indentation, uses short closing tags and removes the <SatelliteListcopy> element from format 105/110.
Onka does not update chanLst.bin (which isn't required when only DVBS.xml is modified since that file has no checksum in chanLst.bin)
Nevertheless a user reported that swapping DVB-S channels 1 and 2 with Onka on a TV that uses this xml-only format 110 worked for him.
There seem to be 3 different flavors or the "100" format:
One has only .xml files in the channellib and s2channellib folders, does not indent lines in the .xml files, has a fixed number of bytes for channel and satellite names (padded with 0x00) and has no "Scramble" attribute.
And a version that has dtv_cmdb_*.bin next to the .xml files, uses 4 spaces for indentation, only writes as many bytes for names as needed and has a "Scramble" attribute.
While the first seems to work fine when XML nodes are reordered by their new programNr, the latter seems to get confused when the .bin and .xml files have different data record orders. This is still under investigation.
The Philips editor does not modify these .bin files, appends 0x00 padding to the channel names, changes indentation to 2 tabs and strips the Scramble attribute. It's likely it wasn't designed for this type of list.
<Channel>
<Setup SatelliteName="0x54 0x00 0x55 0x00 0x52 0x00 0x4B 0x00 0x53 0x00 0x41 0x00 0x54 0x00 0x20 0x00 0x34 0x00 0x32 0x00 0x45 0x00 " ChannelNumber="1" ChannelName="0x54 0x00 0xC4 0x00 0xB0 0x00 0x56 0x00 0xC4 0x00 0xB0 0x00 0x42 0x00 0x55 0x00 0x20 0x00 0x53 0x00 0x50 0x00 0x4F 0x00 0x52 0x00 " ChannelLock="0" UserModifiedName="0" LogoID="0" UserModifiedLogo="0" LogoLock="0" UserHidden="0" FavoriteNumber="0" />
@@ -104,17 +109,17 @@ namespace ChanSort.Loader.Philips
this.DataRoot.AddChannelList(this.allSatChannels);
//this.DataRoot.AddChannelList(this.favChannels); // format 100.0 does not support mixed source favs and adding it would automatically switch to mixed source fav mode
this.dvbtChannels.VisibleColumnFieldNames.Add("Source");
this.dvbcChannels.VisibleColumnFieldNames.Add("Source");
this.dvbtChannels.VisibleColumnFieldNames.Add(nameof(ChannelInfo.Source));
this.dvbcChannels.VisibleColumnFieldNames.Add(nameof(ChannelInfo.Source));
foreach (var list in this.DataRoot.ChannelLists)
{
list.VisibleColumnFieldNames.Remove("PcrPid");
list.VisibleColumnFieldNames.Remove("VideoPid");
list.VisibleColumnFieldNames.Remove("AudioPid");
list.VisibleColumnFieldNames.Remove("Skip");
list.VisibleColumnFieldNames.Remove("ShortName");
list.VisibleColumnFieldNames.Remove("Provider");
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.PcrPid));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.VideoPid));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.AudioPid));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Skip));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.ShortName));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Provider));
}
this.analogChannels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.OriginalNetworkId));
@@ -301,14 +306,15 @@ namespace ChanSort.Loader.Philips
if (setupNode.HasAttribute("name"))
{
file.formatVersion = 1;
this.iniMapSection = ini.GetSection("Repair_xml");
this.Features.FavoritesMode = FavoritesMode.None;
foreach (var list in this.DataRoot.ChannelLists)
{
list.VisibleColumnFieldNames.Remove("Favorites");
list.VisibleColumnFieldNames.Remove("Lock");
list.VisibleColumnFieldNames.Remove("Hidden");
list.VisibleColumnFieldNames.Remove("ServiceTypeName");
list.VisibleColumnFieldNames.Remove("Encrypted");
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Favorites));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Lock));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Hidden));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.ServiceTypeName));
list.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Encrypted));
}
}
else if (setupNode.HasAttribute("ChannelName"))
@@ -325,7 +331,7 @@ namespace ChanSort.Loader.Philips
else if (dtype == "3")
medium = "dvbs";
hasEncrypt = setupNode.HasAttribute("Scrambled");
hasEncrypt = setupNode.HasAttribute("Scramble") || setupNode.HasAttribute("Scrambled");
}
else
throw new FileLoadException("Unknown data format");
@@ -354,16 +360,27 @@ namespace ChanSort.Loader.Philips
chList?.VisibleColumnFieldNames.Remove("Encrypted");
var ver = this.chanLstBin?.VersionMajor ?? 0;
this.iniMapSection = ini.GetSection("Map" + ver);
if (ver > 0)
this.iniMapSection = ini.GetSection("Map" + ver);
if (ver >= 105)
this.Features.FavoritesMode = FavoritesMode.OrderedPerSource;
this.Features.FavoritesMode = FavoritesMode.OrderedPerSource; // will be overridden when a Favorite.xml file is found
else if (ver == 100)
{
// use special configs for version 100 variants
var dir = Path.GetDirectoryName(this.FileName) ?? "";
if (File.Exists(Path.Combine(dir, "atv_cmdb.bin")))
this.iniMapSection = ini.GetSection("Map100_cmdb.bin");
else if (File.Exists(Path.Combine(dir, "channelFile.bin")))
this.iniMapSection = ini.GetSection("Map100_channelFile.bin");
if (this.iniMapSection?.GetBool("setReorderedFavNumber") ?? false)
this.Features.FavoritesMode = FavoritesMode.OrderedPerSource;
}
if (this.iniMapSection?.GetBool("allowDelete", false) ?? false)
this.Features.DeleteMode = DeleteMode.Physically;
return chList;
}
#endregion
@@ -386,9 +403,9 @@ namespace ChanSort.Loader.Philips
chan.OldProgramNr = -1;
chan.IsDeleted = false;
if (file.formatVersion == 1)
this.ParseRepairFormat(data, chan);
this.ParseRepairXml(data, chan);
else if (file.formatVersion == 2)
this.ParseChannelMapFormat(data, chan);
this.ParseChannelMapXml(data, chan);
if ((chan.SignalSource & SignalSource.MaskAdInput) == SignalSource.DvbT)
chan.ChannelOrTransponder = LookupData.Instance.GetDvbtTransponder(chan.FreqInMhz).ToString();
@@ -399,8 +416,8 @@ namespace ChanSort.Loader.Philips
}
#endregion
#region ParseRepairFormat
private void ParseRepairFormat(Dictionary<string, string> data, Channel chan)
#region ParseRepairXml()
private void ParseRepairXml(Dictionary<string, string> data, Channel chan)
{
chan.Format = 1;
chan.OldProgramNr = ParseInt(data.TryGet("presetnumber"));
@@ -419,8 +436,8 @@ namespace ChanSort.Loader.Philips
}
#endregion
#region ParseChannelMapFormat
private void ParseChannelMapFormat(Dictionary<string,string> data, Channel chan)
#region ParseChannelMapXml()
private void ParseChannelMapXml(Dictionary<string,string> data, Channel chan)
{
chan.Format = 2;
chan.RawSatellite = data.TryGet("SatelliteName");
@@ -459,11 +476,11 @@ namespace ChanSort.Loader.Philips
chan.Polarity = pol == "0" ? 'H' : 'V';
chan.Hidden |= data.TryGet("SystemHidden") == "1";
chan.Encrypted = data.TryGet("Scrambled") == "1"; // introduced in ChannelMap_105 format
chan.Encrypted = data.TryGet("Scramble") == "1" || data.TryGet("Scrambled") == "1"; // v100 sometimes contains a "Scramble", v105/v110 always contain "Scrambled"
}
#endregion
#region ReadFavList
#region ReadFavList()
private void ReadFavList(XmlNode node)
{
int index = ParseInt(node.Attributes["Index"].InnerText);
@@ -544,10 +561,18 @@ namespace ChanSort.Loader.Philips
this.UpdateChannelList(list);
}
var reorderNodes = this.iniMapSection?.GetBool("reorderXmlNodesByChannelNumber", true) ?? true;
// It is unclear whether XML nodes must be sorted by the new program number or kept in the original order. This may be different for the various format versions.
// Onka, which was made for the ChannelMap_100 flavor that doesn't export dtv_cmdb_2.bin files, reorders the XML nodes and users reported that it works.
// The official Philips Editor 6.61.22 does not reorder the XML nodes and does not change dtv_cmdb_*.bin when editing a ChannelMap_100 folder. But it is unclear if this editor is designed to handle the cmdb flavor.
// A user with a ChannelMap_100 export including a dtv_cmdb_2.bin reported, that the TV shows the reordered list in the menu, but tunes the channels based on the original numbers.
// It's unclear if that happenes because the XML was reordered and out-of-sync with the .bin, or if the TV always uses the .bin for tuning and XML edits are moot.
// On top of that this TV messed up Umlauts during the import, despite ChanSort writing the exact same name data in hex-encoded UTF16. The result was as if the string was exported as UTF-8 bytes and then parsed with an 8-bit code page.
var reorderNodes = this.iniMapSection?.GetBool("reorderRecordsByChannelNumber") ?? false;
foreach (var file in this.fileDataList)
{
if (reorderNodes && Path.GetFileName(file.path).ToLowerInvariant().StartsWith("dvb"))
if (reorderNodes && (file.formatVersion == 1 || Path.GetFileName(file.path).ToLowerInvariant().StartsWith("dvb")))
this.ReorderNodes(file);
var satelliteListcopy = this.iniMapSection?.GetString("satelliteListcopy") ?? "";
var nodeList = file.doc.GetElementsByTagName("SatelliteListcopy");
@@ -576,6 +601,7 @@ namespace ChanSort.Loader.Philips
#region UpdateChannelList()
private void UpdateChannelList(ChannelList list)
{
var padChannelNameBytes = this.iniMapSection?.GetBool("padChannelName", true) ?? true;
var setFavoriteNumber = this.iniMapSection?.GetBool("setFavoriteNumber", false) ?? false;
var userReorderChannel = this.iniMapSection?.GetString("userReorderChannel") ?? "";
@@ -592,16 +618,16 @@ namespace ChanSort.Loader.Philips
}
if (ch.Format == 1)
this.UpdateRepairFormat(ch);
this.UpdateRepairXml(ch);
else if (ch.Format == 2)
this.UpdateChannelMapFormat(ch, setFavoriteNumber, userReorderChannel);
this.UpdateChannelMapXml(ch, padChannelNameBytes, setFavoriteNumber, userReorderChannel);
}
}
#endregion
#region UpdateRepairFormat()
#region UpdateRepairXml()
private void UpdateRepairFormat(Channel ch)
private void UpdateRepairXml(Channel ch)
{
ch.SetupNode.Attributes["presetnumber"].Value = ch.NewProgramNr.ToString();
if (ch.IsNameModified)
@@ -609,42 +635,59 @@ namespace ChanSort.Loader.Philips
}
#endregion
#region UpdateChannelMapFormat()
private void UpdateChannelMapFormat(Channel ch, bool setFavoriteNumber, string userReorderChannel)
#region UpdateChannelMapXml()
private void UpdateChannelMapXml(Channel ch, bool paddedName, bool setFavoriteNumber, string userReorderChannel)
{
ch.SetupNode.Attributes["ChannelNumber"].Value = ch.NewProgramNr.ToString();
var setup = ch.SetupNode.Attributes;
setup["ChannelNumber"].Value = ch.NewProgramNr.ToString();
if (ch.IsNameModified)
{
ch.SetupNode.Attributes["ChannelName"].InnerText = EncodeName(ch.Name, (ch.SetupNode.Attributes["ChannelName"].InnerText.Length + 1) / 5, true);
var attr = ch.SetupNode.Attributes["UserModifiedName"];
setup["ChannelName"].InnerText = EncodeName(ch.Name, 50, paddedName, paddedName);
var attr = setup["UserModifiedName"];
if (attr != null)
attr.InnerText = "1";
}
// ChannelMap_100 supports a single fav list and stores the favorite number directly here in the channel.
// The official Philips editor forces the favorites to be in the same order as the main program number. I don't know if this is a requirement or just a limitation of the editor.
setup["ChannelLock"].Value = ch.Lock ? "1" : "0";
setup["UserHidden"].Value = ch.Hidden ? "1" : "0";
// ChannelMap_105 and later always store the value 0 in the channel and instead use a separate Favorites.xml file.
ch.SetupNode.Attributes["FavoriteNumber"].Value = setFavoriteNumber ? Math.Max(ch.GetPosition(1), 0).ToString() : "0";
// ChannelMap_100 supports a single fav list and stores the favorite number directly in the channel.
// The official Philips editor allows to reorder favorites when switched to the "Favourite" list view
var urc = ch.SetupNode.Attributes["UserReorderChannel"]; // introduced with format 110, but not always present
if (userReorderChannel == "")
userReorderChannel = "0";
if (userReorderChannel == "delete" || userReorderChannel == "remove")
urc.OwnerElement?.RemoveAttributeNode(urc);
else if (userReorderChannel == "auto")
// ChannelMap_105 and later always store the value 0 and instead use a separate Favorites.xml file with mixed-source channels.
setup["FavoriteNumber"].Value = setFavoriteNumber ? Math.Max(ch.GetPosition(1), 0).ToString() : "0";
// "UserReorderChannel" was introduced with format 110, but not always present.
// It is unclear if this should be 0, 1, or removed for the import to work.
// One user reported a 110 format file edited with Onka (which basically reverted the file to format 100 and removed UserReorderChannel) worked for him,
// while my attempt with ChanSort and setting UserReorderChannel=1 didn't work. But maybe that was due to other factors.
var urc = setup["UserReorderChannel"];
if (urc != null)
{
if (urc != null && ch.OldProgramNr != ch.NewProgramNr)
urc.InnerText = "1";
if (userReorderChannel == "")
userReorderChannel = "0";
switch (userReorderChannel)
{
case "delete":
case "remove":
urc.OwnerElement?.RemoveAttributeNode(urc);
break;
case "auto":
if (ch.OldProgramNr != ch.NewProgramNr)
urc.InnerText = "1";
break;
default:
urc.InnerText = userReorderChannel;
break;
}
}
else if (urc != null)
urc.InnerText = userReorderChannel;
}
#endregion
#region UpdateFavList
#region UpdateFavList()
private void UpdateFavList()
{
var favFile = this.fileDataList.FirstOrDefault(fd => Path.GetFileName(fd.path).ToLowerInvariant() == "favorite.xml");
@@ -658,7 +701,7 @@ namespace ChanSort.Loader.Philips
favListNode.InnerXml = ""; // clear all <FavoriteChannel> child elements but keep the attributes of the current node
var attr = favListNode.Attributes?["Name"];
if (attr != null)
attr.InnerText = EncodeName(this.favChannels.GetFavListCaption(index - 1), (attr.InnerText.Length + 1)/5, false);
attr.InnerText = EncodeName(this.favChannels.GetFavListCaption(index - 1), (attr.InnerText.Length + 1)/5 /* 64 */, true, false);
// increment fav list version, unless disabled in .ini file
if (chanLstBin != null && (ini.GetSection("Map" + chanLstBin.VersionMajor)?.GetBool("incrementFavListVersion", true) ?? true))
@@ -686,28 +729,32 @@ namespace ChanSort.Loader.Philips
}
#endregion
#region EncodeName
private string EncodeName(string name, int numBytes, bool upperCaseHexDigits)
#region EncodeName()
private string EncodeName(string name, int maxBytes, bool padBytes, bool upperCaseHexDigits)
{
var bytes = Encoding.Unicode.GetBytes(name);
var sb = new StringBuilder();
var pattern = upperCaseHexDigits ? "0x{0:X2} " : "0x{0:x2} ";
for (int i = 0; i < numBytes - 2; i++)
var len = Math.Min(bytes.Length, padBytes ? maxBytes-2 : maxBytes); // when padding, always add a 0x00 0x00 end-of-string
int i;
for (i = 0; i < len; i++)
sb.AppendFormat(pattern, bytes[i]);
if (padBytes)
{
var b = i < bytes.Length ? bytes[i] : 0;
sb.AppendFormat(pattern, b);
for (; i < maxBytes; i++)
sb.Append("0x00 ");
sb.Remove(sb.Length - 1, 1);
}
sb.Append("0x00 0x00"); // always add an end-of-string
return sb.ToString();
}
#endregion
#region ReorderNodes
#region ReorderNodes()
private void ReorderNodes(FileData file)
{
if (file.formatVersion != 2)
return;
var progNrAttrib = file.formatVersion == 1 ? "presetnumber" : "ChannelNumer";
var nodes = file.doc.DocumentElement.GetElementsByTagName("Channel");
var list = new List<XmlElement>();
@@ -715,7 +762,7 @@ namespace ChanSort.Loader.Philips
list.Add((XmlElement)node);
foreach (var node in list)
file.doc.DocumentElement.RemoveChild(node);
foreach(var node in list.OrderBy(elem => int.Parse(elem["Setup"].Attributes["ChannelNumber"].InnerText)))
foreach(var node in list.OrderBy(elem => int.Parse(elem["Setup"].Attributes[progNrAttrib].InnerText)))
file.doc.DocumentElement.AppendChild(node);
}
#endregion
@@ -758,10 +805,13 @@ namespace ChanSort.Loader.Philips
}
#endregion
#region GetFileInformation()
public override string GetFileInformation()
{
return base.GetFileInformation() + this.logMessages.Replace("\n", "\r\n");
}
#endregion
#region class FileData
private class FileData

View File

@@ -1118,6 +1118,7 @@
this.barManager1.MainMenu = this.bar1;
this.barManager1.MaxItemId = 115;
this.barManager1.ShowFullMenus = true;
this.barManager1.ShortcutItemClick += new DevExpress.XtraBars.ShortcutItemClickEventHandler(this.barManager1_ShortcutItemClick);
//
// bar1
//

View File

@@ -669,7 +669,10 @@ namespace ChanSort.Ui
private void InitInitialChannelOrder()
{
if (this.DataRoot.ChannelLists.All(l => l.Count == 0 || l.ReadOnly))
{
this.DataRoot.ApplyCurrentProgramNumbers(); // otherwise there wouldn't be any numbers in single pane view
return;
}
DialogResult res;
var msg = Resources.MainForm_InitInitialChannelOrder_Question;
@@ -2061,6 +2064,7 @@ namespace ChanSort.Ui
}
#endregion
// UI events
#region MainForm_Shown
@@ -2684,6 +2688,111 @@ namespace ChanSort.Ui
#endregion
#region gview_MouseDown, gview_MouseUp, timerEditDelay_Tick, gview_ShowingEditor
// these 4 event handler in combination override the default row-selection and editor-opening
// behavior of the grid control.
private bool dontFocusClickedRow;
private void gview_MouseDown(object sender, MouseEventArgs e)
{
var view = (GridView)sender;
this.downHit = view.CalcHitInfo(e.Location);
this.dragDropInfo = null;
if (!view.IsDataRow(downHit.RowHandle))
return;
if (e.Button == MouseButtons.Left)
{
if (ModifierKeys == Keys.None)
{
if (downHit.RowHandle != view.FocusedRowHandle && !dontFocusClickedRow)
SelectFocusedRow(view, downHit.RowHandle);
this.timerEditDelay.Start();
}
else
{
if (ModifierKeys == Keys.Control && !view.IsRowSelected(downHit.RowHandle))
this.BeginInvoke((Action)(() => view.SelectRow(downHit.RowHandle)));
}
}
else if (e.Button == MouseButtons.Right)
{
if (!view.IsRowSelected(downHit.RowHandle))
SelectFocusedRow(view, downHit.RowHandle);
}
this.dontOpenEditor = true;
this.dontFocusClickedRow = false;
}
private void gview_MouseUp(object sender, MouseEventArgs e)
{
this.timerEditDelay.Stop();
this.BeginInvoke((Action)(() => { this.dontOpenEditor = false; }));
}
private void timerEditDelay_Tick(object sender, EventArgs e)
{
this.timerEditDelay.Stop();
this.dontOpenEditor = false;
if (this.lastFocusedGrid != null)
{
var hit = this.lastFocusedGrid.CalcHitInfo(this.lastFocusedGrid.GridControl.PointToClient(MousePosition));
if (hit.Column == this.lastFocusedGrid.FocusedColumn && hit.RowHandle == this.lastFocusedGrid.FocusedRowHandle)
this.lastFocusedGrid.ShowEditor();
}
}
private void gview_ShowingEditor(object sender, CancelEventArgs e)
{
var field = ((GridView)sender).FocusedColumn.FieldName;
if (this.dontOpenEditor && (field == this.colSlotNew.FieldName || field == this.colName.FieldName))
e.Cancel = true;
}
#endregion
#region gview_ShownEditor, gview_KeyPress
private void gview_ShownEditor(object sender, EventArgs e)
{
var view = (GridView)sender;
if (view.FocusedRowHandle < 0)
return;
var edit = view.ActiveEditor as TextEdit;
if (edit == null) return;
edit.Properties.MaxLength = view.FocusedColumn.FieldName == "Name" ? this.CurrentChannelList.MaxChannelNameLength : 0;
}
private void gview_KeyPress(object sender, KeyPressEventArgs e)
{
var view = (GridView)sender;
if (view.FocusedColumn.DisplayFormat.FormatType == FormatType.Numeric && (e.KeyChar < '0' || e.KeyChar > '9'))
e.Handled = true;
}
#endregion
#region gviewLeft_LayoutUpgrade, gviewRight_LayoutUpgrade
private void gviewLeft_LayoutUpgrade(object sender, LayoutUpgradeEventArgs e)
{
this.gviewLeft.ClearGrouping();
this.gviewLeft.OptionsCustomization.AllowGroup = false;
}
private void gviewRight_LayoutUpgrade(object sender, LayoutUpgradeEventArgs e)
{
this.gviewRight.ClearGrouping();
this.gviewRight.OptionsCustomization.AllowGroup = false;
}
#endregion
#region rbInsertMode_CheckedChanged
private void rbInsertMode_CheckedChanged(object sender, EventArgs e)
@@ -2961,6 +3070,23 @@ namespace ChanSort.Ui
// -- menus
#region barManager1_ShortcutItemClick
private void barManager1_ShortcutItemClick(object sender, ShortcutItemClickEventArgs e)
{
if (e.Shortcut.Key == Keys.Delete)
{
// the Del hotkey to remove a channel is only allowed when a grid is focused and no editor is open
if (this.gridLeft.ContainsFocus)
e.Cancel |= this.gviewLeft.ActiveEditor != null;
else if (this.gridRight.ContainsFocus)
e.Cancel |= this.gviewRight.ActiveEditor != null;
else
e.Cancel = true;
}
}
#endregion
#region File menu
private void miOpen_ItemClick(object sender, ItemClickEventArgs e)
@@ -3306,6 +3432,60 @@ namespace ChanSort.Ui
}
#endregion
#region miCheckUpdates_ItemClick
private void miCheckUpdates_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
if (this.miCheckUpdates.Down == Config.Default.CheckForUpdates)
return;
if (this.miCheckUpdates.Down)
UpdateCheck.CheckForNewVersion();
this.SaveSettings();
}
catch (Exception ex)
{
HandleException(ex);
}
}
#endregion
#region miExplorerIntegration_ItemClick
private void miExplorerIntegration_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
if (this.miExplorerIntegration.Down == Config.Default.ExplorerIntegration)
return;
// get all file extensions from loader plugins
var ext = new HashSet<string>();
foreach (var loader in this.Plugins)
{
var filters = loader.FileFilter.Split(';');
foreach (var filter in filters)
{
int i = filter.LastIndexOf('.');
if (i >= 0 && i < filter.Length - 1)
ext.Add(filter.Substring(i).ToLowerInvariant());
}
}
if (this.miExplorerIntegration.Down)
FileAssociations.CreateMissingAssociations(ext);
else
FileAssociations.DeleteAssociations(ext);
this.SaveSettings();
}
catch (Exception ex)
{
HandleException(ex);
}
}
#endregion
#endregion
#region Help menu
@@ -3392,163 +3572,7 @@ namespace ChanSort.Ui
#endregion
#region miExplorerIntegration_ItemClick
private void miExplorerIntegration_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
if (this.miExplorerIntegration.Down == Config.Default.ExplorerIntegration)
return;
// get all file extensions from loader plugins
var ext = new HashSet<string>();
foreach (var loader in this.Plugins)
{
var filters = loader.FileFilter.Split(';');
foreach (var filter in filters)
{
int i = filter.LastIndexOf('.');
if (i >= 0 && i < filter.Length - 1)
ext.Add(filter.Substring(i).ToLowerInvariant());
}
}
if (this.miExplorerIntegration.Down)
FileAssociations.CreateMissingAssociations(ext);
else
FileAssociations.DeleteAssociations(ext);
this.SaveSettings();
}
catch (Exception ex)
{
HandleException(ex);
}
}
#endregion
#region miCheckUpdates_ItemClick
private void miCheckUpdates_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
if (this.miCheckUpdates.Down == Config.Default.CheckForUpdates)
return;
if (this.miCheckUpdates.Down)
UpdateCheck.CheckForNewVersion();
this.SaveSettings();
}
catch (Exception ex)
{
HandleException(ex);
}
}
#endregion
#region gview_MouseDown, gview_MouseUp, timerEditDelay_Tick, gview_ShowingEditor
// these 4 event handler in combination override the default row-selection and editor-opening
// behavior of the grid control.
private bool dontFocusClickedRow;
private void gview_MouseDown(object sender, MouseEventArgs e)
{
var view = (GridView) sender;
this.downHit = view.CalcHitInfo(e.Location);
this.dragDropInfo = null;
if (!view.IsDataRow(downHit.RowHandle))
return;
if (e.Button == MouseButtons.Left)
{
if (ModifierKeys == Keys.None)
{
if (downHit.RowHandle != view.FocusedRowHandle && !dontFocusClickedRow)
SelectFocusedRow(view, downHit.RowHandle);
this.timerEditDelay.Start();
}
else
{
if (ModifierKeys == Keys.Control && !view.IsRowSelected(downHit.RowHandle))
this.BeginInvoke((Action) (() => view.SelectRow(downHit.RowHandle)));
}
}
else if (e.Button == MouseButtons.Right)
{
if (!view.IsRowSelected(downHit.RowHandle))
SelectFocusedRow(view, downHit.RowHandle);
}
this.dontOpenEditor = true;
this.dontFocusClickedRow = false;
}
private void gview_MouseUp(object sender, MouseEventArgs e)
{
this.timerEditDelay.Stop();
this.BeginInvoke((Action) (() => { this.dontOpenEditor = false; }));
}
private void timerEditDelay_Tick(object sender, EventArgs e)
{
this.timerEditDelay.Stop();
this.dontOpenEditor = false;
if (this.lastFocusedGrid != null)
{
var hit = this.lastFocusedGrid.CalcHitInfo(this.lastFocusedGrid.GridControl.PointToClient(MousePosition));
if (hit.Column == this.lastFocusedGrid.FocusedColumn && hit.RowHandle == this.lastFocusedGrid.FocusedRowHandle)
this.lastFocusedGrid.ShowEditor();
}
}
private void gview_ShowingEditor(object sender, CancelEventArgs e)
{
var field = ((GridView) sender).FocusedColumn.FieldName;
if (this.dontOpenEditor && (field == this.colSlotNew.FieldName || field == this.colName.FieldName))
e.Cancel = true;
}
#endregion
#region gview_ShownEditor, gview_KeyPress
private void gview_ShownEditor(object sender, EventArgs e)
{
var view = (GridView) sender;
if (view.FocusedRowHandle < 0)
return;
var edit = view.ActiveEditor as TextEdit;
if (edit == null) return;
edit.Properties.MaxLength = view.FocusedColumn.FieldName == "Name" ? this.CurrentChannelList.MaxChannelNameLength : 0;
}
private void gview_KeyPress(object sender, KeyPressEventArgs e)
{
var view = (GridView) sender;
if (view.FocusedColumn.DisplayFormat.FormatType == FormatType.Numeric && (e.KeyChar < '0' || e.KeyChar > '9'))
e.Handled = true;
}
#endregion
#region gviewLeft_LayoutUpgrade, gviewRight_LayoutUpgrade
private void gviewLeft_LayoutUpgrade(object sender, LayoutUpgradeEventArgs e)
{
this.gviewLeft.ClearGrouping();
this.gviewLeft.OptionsCustomization.AllowGroup = false;
}
private void gviewRight_LayoutUpgrade(object sender, LayoutUpgradeEventArgs e)
{
this.gviewRight.ClearGrouping();
this.gviewRight.OptionsCustomization.AllowGroup = false;
}
#endregion
#region btnClearLeftFilter_Click, btnClearRightFilter_Click
@@ -3674,8 +3698,7 @@ namespace ChanSort.Ui
}
}
}
#endregion
}
}

View File

@@ -276,7 +276,7 @@
<value>gridLeft</value>
</data>
<data name="&gt;&gt;gridLeft.Type" xml:space="preserve">
<value>ChanSort.XGridControl, ChanSort, Version=1.0.7877.25236, Culture=neutral, PublicKeyToken=null</value>
<value>ChanSort.XGridControl, ChanSort, Version=1.0.7917.21172, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;gridLeft.Parent" xml:space="preserve">
<value>grpOutputList</value>
@@ -798,7 +798,7 @@
<data name="barManager1.Categories" type="DevExpress.XtraBars.BarManagerCategory, DevExpress.XtraBars.v21.1" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAF1EZXZFeHByZXNzLlh0cmFCYXJzLnYyMS4xLCBWZXJzaW9uPTIx
LjEuNC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
LjEuNS4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
ACZEZXZFeHByZXNzLlh0cmFCYXJzLkJhck1hbmFnZXJDYXRlZ29yeQMAAAAETmFtZQRHdWlkB1Zpc2li
bGUBAwALU3lzdGVtLkd1aWQBAgAAAAYDAAAABEZpbGUE/P///wtTeXN0ZW0uR3VpZAsAAAACX2ECX2IC
X2MCX2QCX2UCX2YCX2cCX2gCX2kCX2oCX2sAAAAAAAAAAAAAAAgHBwICAgICAgICKaPJ5gsBeU2NTSFe
@@ -808,7 +808,7 @@
<data name="barManager1.Categories1" type="DevExpress.XtraBars.BarManagerCategory, DevExpress.XtraBars.v21.1" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAF1EZXZFeHByZXNzLlh0cmFCYXJzLnYyMS4xLCBWZXJzaW9uPTIx
LjEuNC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
LjEuNS4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
ACZEZXZFeHByZXNzLlh0cmFCYXJzLkJhck1hbmFnZXJDYXRlZ29yeQMAAAAETmFtZQRHdWlkB1Zpc2li
bGUBAwALU3lzdGVtLkd1aWQBAgAAAAYDAAAABEhlbHAE/P///wtTeXN0ZW0uR3VpZAsAAAACX2ECX2IC
X2MCX2QCX2UCX2YCX2cCX2gCX2kCX2oCX2sAAAAAAAAAAAAAAAgHBwICAgICAgICdEVVDegwMU2acNpw
@@ -818,7 +818,7 @@
<data name="barManager1.Categories2" type="DevExpress.XtraBars.BarManagerCategory, DevExpress.XtraBars.v21.1" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAF1EZXZFeHByZXNzLlh0cmFCYXJzLnYyMS4xLCBWZXJzaW9uPTIx
LjEuNC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
LjEuNS4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
ACZEZXZFeHByZXNzLlh0cmFCYXJzLkJhck1hbmFnZXJDYXRlZ29yeQMAAAAETmFtZQRHdWlkB1Zpc2li
bGUBAwALU3lzdGVtLkd1aWQBAgAAAAYDAAAABEVkaXQE/P///wtTeXN0ZW0uR3VpZAsAAAACX2ECX2IC
X2MCX2QCX2UCX2YCX2cCX2gCX2kCX2oCX2sAAAAAAAAAAAAAAAgHBwICAgICAgICZMTu18lZRU+IqmAu
@@ -828,7 +828,7 @@
<data name="barManager1.Categories3" type="DevExpress.XtraBars.BarManagerCategory, DevExpress.XtraBars.v21.1" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAF1EZXZFeHByZXNzLlh0cmFCYXJzLnYyMS4xLCBWZXJzaW9uPTIx
LjEuNC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
LjEuNS4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
ACZEZXZFeHByZXNzLlh0cmFCYXJzLkJhck1hbmFnZXJDYXRlZ29yeQMAAAAETmFtZQRHdWlkB1Zpc2li
bGUBAwALU3lzdGVtLkd1aWQBAgAAAAYDAAAAB09wdGlvbnME/P///wtTeXN0ZW0uR3VpZAsAAAACX2EC
X2ICX2MCX2QCX2UCX2YCX2cCX2gCX2kCX2oCX2sAAAAAAAAAAAAAAAgHBwICAgICAgICXJMOh9nzAkKc
@@ -838,7 +838,7 @@
<data name="barManager1.Categories4" type="DevExpress.XtraBars.BarManagerCategory, DevExpress.XtraBars.v21.1" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAF1EZXZFeHByZXNzLlh0cmFCYXJzLnYyMS4xLCBWZXJzaW9uPTIx
LjEuNC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
LjEuNS4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI4OGQxNzU0ZDcwMGU0OWEFAQAA
ACZEZXZFeHByZXNzLlh0cmFCYXJzLkJhck1hbmFnZXJDYXRlZ29yeQMAAAAETmFtZQRHdWlkB1Zpc2li
bGUBAwALU3lzdGVtLkd1aWQBAgAAAAYDAAAADUFjY2Vzc2liaWxpdHkE/P///wtTeXN0ZW0uR3VpZAsA
AAACX2ECX2ICX2MCX2QCX2UCX2YCX2cCX2gCX2kCX2oCX2sAAAAAAAAAAAAAAAgHBwICAgICAgICeIvz
@@ -1226,7 +1226,7 @@
<value>gviewLeft</value>
</data>
<data name="&gt;&gt;gviewLeft.Type" xml:space="preserve">
<value>ChanSort.XGridView, ChanSort, Version=1.0.7877.25236, Culture=neutral, PublicKeyToken=null</value>
<value>ChanSort.XGridView, ChanSort, Version=1.0.7917.21172, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;colIndex1.Name" xml:space="preserve">
<value>colIndex1</value>
@@ -1310,13 +1310,13 @@
<value>globalImageCollection1</value>
</data>
<data name="&gt;&gt;globalImageCollection1.Type" xml:space="preserve">
<value>ChanSort.Ui.GlobalImageCollection, ChanSort, Version=1.0.7877.25236, Culture=neutral, PublicKeyToken=null</value>
<value>ChanSort.Ui.GlobalImageCollection, ChanSort, Version=1.0.7917.21172, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;gviewRight.Name" xml:space="preserve">
<value>gviewRight</value>
</data>
<data name="&gt;&gt;gviewRight.Type" xml:space="preserve">
<value>ChanSort.XGridView, ChanSort, Version=1.0.7877.25236, Culture=neutral, PublicKeyToken=null</value>
<value>ChanSort.XGridView, ChanSort, Version=1.0.7917.21172, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;colIndex.Name" xml:space="preserve">
<value>colIndex</value>
@@ -2075,7 +2075,7 @@
<value>DevExpress.XtraEditors.XtraForm, DevExpress.Utils.v21.1, Version=21.1.5.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a</value>
</data>
<data name="SharedImageCollection.Timestamp" type="System.DateTime, mscorlib">
<value>07/26/2021 14:06:54</value>
<value>09/04/2021 11:58:02</value>
</data>
<data name="SharedImageCollection.ImageSize" type="System.Drawing.Size, System.Drawing">
<value>16, 16</value>
@@ -2946,7 +2946,7 @@
<value>gridRight</value>
</data>
<data name="&gt;&gt;gridRight.Type" xml:space="preserve">
<value>ChanSort.XGridControl, ChanSort, Version=1.0.7877.25236, Culture=neutral, PublicKeyToken=null</value>
<value>ChanSort.XGridControl, ChanSort, Version=1.0.7917.21172, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;gridRight.Parent" xml:space="preserve">
<value>grpInputList</value>
@@ -3248,7 +3248,4 @@
<metadata name="timerSelectFocusedRow.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1153, 17</value>
</metadata>
<data name="mnuLanguages.Caption" xml:space="preserve">
<value>&amp;Language</value>
</data>
</root>

View File

@@ -1,17 +1,27 @@
ChanSort Change Log
===================
2021-08-31
- ChanSort didn't work properly for Turkish (and other system locales) that don't translate ".bin" to uppercase
".BIN" and ".BIN" to lowercase ".bin".
- Sony: Files with incorrect checksum are no longer rejected. Information about a bad checksum is visible
unter File / File Information. (The TV seems to ignore bad checksums during the import and the official
Sony PC Editor ignores bad checksums and write incorrect ones, depending on the file format version)
- Philips: Removing a channel from a list is no longer possible (because it is not supported by the TV's import).
When saving a file, all unsorted channels will be placed at the end of the list.
- Added read-only support for Philips Repair\\Mgr_chan_s_fta.db lists. Files can be used as a reference list,
but modifying them won't be possible.
- Updated Hungarian translation. Thanks to efi99 on Github!
2021-09-04 (pre-release)
- ChanSort didn't work properly with Windows region settings that don't convert ".BIN" to lowercase ".bin" (e.g. Turkey)
- Philips: added ChanSort.Loader.Philips.ini file to try out different configurations until working ones get confirmed.
- Philips: disabled deleting channels for most file formats (they require files for menu and tuner to be kept in-sync).
- Philips: identified several variants of ChannelMap_100 format which now have special handling.
one that exports \*cmdb\*.bin files is now fully tested and working.
ones that export only .xml files inside the channellib and s2channellib folders should work too, but not confirmed.
- Philips: ChannelFormat_105 and 110 specific settings in .ini, currently best-effort without user confirmation.
- Philips: added support for Repair\\Mgr_chan_s_fta.db lists. Can be read as a reference list, but editing is
currently disabled in the .ini file (enabling it is experimental)
- added experimental support for 8 variants of "dtv_cmdb_2.bin" DVB-S channel lists (DVB-C/T not supported yet).
Brands known to use this format include Sharp, Toshiba, Dyon, OK.
Philips also uses this format as part of ChannelMap_100, but only for the tuner data and uses .xml for the menu.
All variants need specific configuration in the ChanSort.Loader.CmdbBin.ini file. If your file is not supported yet,
please send it to me via github or email.
- Sony: Files with incorrect checksum are no longer rejected, as the TV seems to ignore bad checksums.
Information about a bad checksum is visible under File / File Information.
- updated Hungarian translation. Thanks to efi99 on Github!
- pressing the "Del"-key on the keyboard no longer deletes a channel when a text editor is open
- dragging a file (or something else) from outside ChanSort over the ChanSort window no longer creates an error
- opening a file containing a read-only channel list now shows the original numbers
2021-07-27
- Philips ChannelMap\_100: fixed reading/writing favorites