mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-01-16 04:12:03 +01:00
- 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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
1
source/ChanSort/MainForm.Designer.cs
generated
1
source/ChanSort/MainForm.Designer.cs
generated
@@ -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
|
||||
//
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@
|
||||
<value>gridLeft</value>
|
||||
</data>
|
||||
<data name=">>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=">>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=">>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=">>colIndex1.Name" xml:space="preserve">
|
||||
<value>colIndex1</value>
|
||||
@@ -1310,13 +1310,13 @@
|
||||
<value>globalImageCollection1</value>
|
||||
</data>
|
||||
<data name=">>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=">>gviewRight.Name" xml:space="preserve">
|
||||
<value>gviewRight</value>
|
||||
</data>
|
||||
<data name=">>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=">>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=">>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=">>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>&Language</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user