diff --git a/CUETools.Codecs.ALAC/ALACDotNet.cs b/CUETools.Codecs.ALAC/ALACDotNet.cs index 04e6cbb..e695f27 100644 --- a/CUETools.Codecs.ALAC/ALACDotNet.cs +++ b/CUETools.Codecs.ALAC/ALACDotNet.cs @@ -27,7 +27,7 @@ using CUETools.Codecs; namespace CUETools.Codecs.ALAC { - [AudioDecoderClass("builtin alac", "m4a")] + [AudioDecoderClass("cuetools", "m4a", 2)] public class ALACReader : IAudioSource { public ALACReader(string path, Stream IO) diff --git a/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp b/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp index 09fd21e..4947ff0 100644 --- a/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp +++ b/CUETools.Codecs.APE/CUETools.Codecs.APE.cpp @@ -101,7 +101,7 @@ namespace CUETools { namespace Codecs { namespace APE { GCHandle _gchBuffer; }; - [AudioDecoderClass("MAC_SDK", "ape")] + [AudioDecoderClass("MAC_SDK", "ape", 1)] public ref class APEReader : public IAudioSource { public: diff --git a/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp b/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp index f835bb2..2cdc518 100644 --- a/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp +++ b/CUETools.Codecs.FLAC/CUETools.Codecs.FLAC.cpp @@ -72,7 +72,7 @@ namespace CUETools { namespace Codecs { namespace FLAC { [UnmanagedFunctionPointer(CallingConvention::Cdecl)] public delegate FLAC__bool DecoderEofDelegate (const FLAC__StreamDecoder *decoder, void *client_data); - [AudioDecoderClass("libFLAC", "flac")] + [AudioDecoderClass("libFLAC", "flac", 1)] public ref class FLACReader : public IAudioSource { public: diff --git a/CUETools.Codecs.FLAKE/FlakeReader.cs b/CUETools.Codecs.FLAKE/FlakeReader.cs index 90a3a31..c4b4f9d 100644 --- a/CUETools.Codecs.FLAKE/FlakeReader.cs +++ b/CUETools.Codecs.FLAKE/FlakeReader.cs @@ -26,7 +26,7 @@ using System.IO; namespace CUETools.Codecs.FLAKE { - [AudioDecoderClass("libFlake", "flac")] + [AudioDecoderClass("cuetools", "flac", 2)] public class FlakeReader: IAudioSource { int[] samplesBuffer; diff --git a/CUETools.Codecs.TTA/CUETools.Codecs.TTA.cpp b/CUETools.Codecs.TTA/CUETools.Codecs.TTA.cpp index dc7aeee..08eafe7 100644 --- a/CUETools.Codecs.TTA/CUETools.Codecs.TTA.cpp +++ b/CUETools.Codecs.TTA/CUETools.Codecs.TTA.cpp @@ -27,7 +27,7 @@ namespace TTA { "operation canceled" }; - [AudioDecoderClass("ttalib", "tta")] + [AudioDecoderClass("ttalib", "tta", 1)] public ref class TTAReader : public IAudioSource { public: diff --git a/CUETools.Codecs.WMA/WMAReader.cs b/CUETools.Codecs.WMA/WMAReader.cs index 986d0d3..74919c6 100644 --- a/CUETools.Codecs.WMA/WMAReader.cs +++ b/CUETools.Codecs.WMA/WMAReader.cs @@ -27,7 +27,7 @@ using System.Runtime.InteropServices; namespace CUETools.Codecs.WMA { - [AudioDecoderClass("windows", "wma")] + [AudioDecoderClass("windows", "wma", 2)] public class WMAReader : IAudioSource { IWMSyncReader m_syncReader; diff --git a/CUETools.Codecs.WavPack/CUETools.Codecs.WavPack.cpp b/CUETools.Codecs.WavPack/CUETools.Codecs.WavPack.cpp index fc0fa1e..2b14aa7 100644 --- a/CUETools.Codecs.WavPack/CUETools.Codecs.WavPack.cpp +++ b/CUETools.Codecs.WavPack/CUETools.Codecs.WavPack.cpp @@ -59,7 +59,7 @@ namespace CUETools { namespace Codecs { namespace WavPack { [UnmanagedFunctionPointer(CallingConvention::Cdecl)] public delegate int DecoderCanSeekDelegate(void *id); - [AudioDecoderClass("libwavpack", "wv")] + [AudioDecoderClass("libwavpack", "wv", 1)] public ref class WavPackReader : public IAudioSource { public: diff --git a/CUETools.Codecs/AudioDecoderClass.cs b/CUETools.Codecs/AudioDecoderClass.cs index 1e4b392..a12d301 100644 --- a/CUETools.Codecs/AudioDecoderClass.cs +++ b/CUETools.Codecs/AudioDecoderClass.cs @@ -21,22 +21,29 @@ namespace CUETools.Codecs [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public sealed class AudioDecoderClass : Attribute { - private string _decoderName, _extension; - public string DecoderName { - get { return _decoderName; } + get; + set; } public string Extension { - get { return _extension; } + get; + set; } - public AudioDecoderClass(string decoderName, string extension) + public int Priority { - _decoderName = decoderName; - _extension = extension; + get; + set; + } + + public AudioDecoderClass(string decoderName, string extension, int priority) + { + DecoderName = decoderName; + Extension = extension; + Priority = priority; } } } diff --git a/CUETools.Codecs/WAVReader.cs b/CUETools.Codecs/WAVReader.cs index 2615fb7..10fd1e2 100644 --- a/CUETools.Codecs/WAVReader.cs +++ b/CUETools.Codecs/WAVReader.cs @@ -3,7 +3,7 @@ using System.IO; namespace CUETools.Codecs { - [AudioDecoderClass("builtin wav", "wav")] + [AudioDecoderClass("cuetools", "wav", 2)] public class WAVReader : IAudioSource { Stream _IO; diff --git a/CUETools.Processor/CUEConfig.cs b/CUETools.Processor/CUEConfig.cs index 5f83392..3865991 100644 --- a/CUETools.Processor/CUEConfig.cs +++ b/CUETools.Processor/CUEConfig.cs @@ -57,7 +57,7 @@ namespace CUETools.Processor public string language; public Dictionary formats; public CUEToolsUDCList encoders; - public Dictionary decoders; + public CUEToolsUDCList decoders; public Dictionary scripts; public string defaultVerifyScript; public string defaultEncodeScript; @@ -81,6 +81,10 @@ namespace CUETools.Processor { get { return encoders; } } + public CUEToolsUDCList Decoders + { + get { return decoders; } + } public CUEConfig() { @@ -151,12 +155,10 @@ namespace CUETools.Processor foreach (Type type in CUEProcessorPlugins.encs) foreach (AudioEncoderClass enc in Attribute.GetCustomAttributes(type, typeof(AudioEncoderClass))) encoders.Add(new CUEToolsUDC(enc, type)); - decoders = new Dictionary(); + decoders = new CUEToolsUDCList(); foreach (Type type in CUEProcessorPlugins.decs) - { - AudioDecoderClass dec = Attribute.GetCustomAttribute(type, typeof(AudioDecoderClass)) as AudioDecoderClass; - decoders.Add(dec.DecoderName, new CUEToolsUDC(dec, type)); - } + foreach (AudioDecoderClass dec in Attribute.GetCustomAttributes(type, typeof(AudioDecoderClass))) + decoders.Add(new CUEToolsUDC(dec, type)); if (Type.GetType("Mono.Runtime", false) == null) { encoders.Add(new CUEToolsUDC("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11 12", "8", "flake.exe", "-%M - -o %O -p %P")); @@ -169,9 +171,9 @@ namespace CUETools.Processor encoders.Add(new CUEToolsUDC("nero aac", "m4a", false, "0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9", "0.4", "neroAacEnc.exe", "-q %M -if - -of %O")); encoders.Add(new CUEToolsUDC("qaac tvbr", "m4a", false, "10 20 30 40 50 60 70 80 90 100 110 127", "80", "qaac.exe", "-s -V %M -q 2 - -o %O")); - decoders.Add("takc", new CUEToolsUDC("takc", "tak", true, "", "", "takc.exe", "-d %I -")); - decoders.Add("ffmpeg alac", new CUEToolsUDC("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-v 0 -i %I -f wav -")); - decoders.Add("wma2wav", new CUEToolsUDC("wma2wav", "wma", true, "", "", "wma2wav.exe", "-s -i %I -w -o -")); + decoders.Add(new CUEToolsUDC("takc", "tak", true, "", "", "takc.exe", "-d %I -")); + decoders.Add(new CUEToolsUDC("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-v 0 -i %I -f wav -")); + decoders.Add(new CUEToolsUDC("wma2wav", "wma", true, "", "", "wma2wav.exe", "-s -i %I -w -o -")); } else { @@ -179,14 +181,14 @@ namespace CUETools.Processor } formats = new Dictionary(); - formats.Add("flac", new CUEToolsFormat("flac", CUEToolsTagger.TagLibSharp, true, false, true, true, true, encoders.GetDefault("flac", true), null, GetDefaultDecoder("flac"))); - formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, true, encoders.GetDefault("wv", true), null, GetDefaultDecoder("wv"))); - formats.Add("ape", new CUEToolsFormat("ape", CUEToolsTagger.TagLibSharp, true, false, false, true, true, encoders.GetDefault("ape", true), null, GetDefaultDecoder("ape"))); - formats.Add("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, false, true, encoders.GetDefault("tta", true), null, GetDefaultDecoder("tta"))); - formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, true, false, true, encoders.GetDefault("wav", true), null, GetDefaultDecoder("wav"))); - formats.Add("m4a", new CUEToolsFormat("m4a", CUEToolsTagger.TagLibSharp, true, true, false, false, true, encoders.GetDefault("m4a", true), encoders.GetDefault("m4a", false), GetDefaultDecoder("m4a"))); - formats.Add("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, true, encoders.GetDefault("tak", true), null, GetDefaultDecoder("tak"))); - formats.Add("wma", new CUEToolsFormat("wma", CUEToolsTagger.TagLibSharp, true, true, false, false, true, encoders.GetDefault("wma", true), null, GetDefaultDecoder("wma"))); + formats.Add("flac", new CUEToolsFormat("flac", CUEToolsTagger.TagLibSharp, true, false, true, true, true, encoders.GetDefault("flac", true), null, decoders.GetDefault("flac", true))); + formats.Add("wv", new CUEToolsFormat("wv", CUEToolsTagger.TagLibSharp, true, false, true, true, true, encoders.GetDefault("wv", true), null, decoders.GetDefault("wv", true))); + formats.Add("ape", new CUEToolsFormat("ape", CUEToolsTagger.TagLibSharp, true, false, false, true, true, encoders.GetDefault("ape", true), null, decoders.GetDefault("ape", true))); + formats.Add("tta", new CUEToolsFormat("tta", CUEToolsTagger.APEv2, true, false, false, false, true, encoders.GetDefault("tta", true), null, decoders.GetDefault("tta", true))); + formats.Add("wav", new CUEToolsFormat("wav", CUEToolsTagger.TagLibSharp, true, false, true, false, true, encoders.GetDefault("wav", true), null, decoders.GetDefault("wav", true))); + formats.Add("m4a", new CUEToolsFormat("m4a", CUEToolsTagger.TagLibSharp, true, true, false, false, true, encoders.GetDefault("m4a", true), encoders.GetDefault("m4a", false), decoders.GetDefault("m4a", true))); + formats.Add("tak", new CUEToolsFormat("tak", CUEToolsTagger.APEv2, true, false, true, true, true, encoders.GetDefault("tak", true), null, decoders.GetDefault("tak", true))); + formats.Add("wma", new CUEToolsFormat("wma", CUEToolsTagger.TagLibSharp, true, true, false, false, true, encoders.GetDefault("wma", true), null, decoders.GetDefault("wma", true))); formats.Add("mp3", new CUEToolsFormat("mp3", CUEToolsTagger.TagLibSharp, false, true, false, false, true, null, encoders.GetDefault("mp3", false), null)); formats.Add("ogg", new CUEToolsFormat("ogg", CUEToolsTagger.TagLibSharp, false, true, false, false, true, null, encoders.GetDefault("ogg", false), null)); @@ -349,13 +351,13 @@ return processor.Go(); sw.Save("ExternalEncoders", nEncoders); int nDecoders = 0; - foreach (KeyValuePair decoder in decoders) - if (decoder.Value.path != null) + foreach (var decoder in decoders) + if (decoder.path != null) { - sw.Save(string.Format("ExternalDecoder{0}Name", nDecoders), decoder.Key); - sw.Save(string.Format("ExternalDecoder{0}Extension", nDecoders), decoder.Value.extension); - sw.Save(string.Format("ExternalDecoder{0}Path", nDecoders), decoder.Value.path); - sw.Save(string.Format("ExternalDecoder{0}Parameters", nDecoders), decoder.Value.parameters); + sw.Save(string.Format("ExternalDecoder{0}Name", nDecoders), decoder.Name); + sw.Save(string.Format("ExternalDecoder{0}Extension", nDecoders), decoder.extension); + sw.Save(string.Format("ExternalDecoder{0}Path", nDecoders), decoder.path); + sw.Save(string.Format("ExternalDecoder{0}Parameters", nDecoders), decoder.parameters); nDecoders++; } sw.Save("ExternalDecoders", nDecoders); @@ -517,8 +519,8 @@ return processor.Go(); string path = sr.Load(string.Format("ExternalDecoder{0}Path", nDecoders)); string parameters = sr.Load(string.Format("ExternalDecoder{0}Parameters", nDecoders)); CUEToolsUDC decoder; - if (!decoders.TryGetValue(name, out decoder)) - decoders.Add(name, new CUEToolsUDC(name, extension, true, "", "", path, parameters)); + if (!decoders.TryGetValue(extension, true, name, out decoder)) + decoders.Add(new CUEToolsUDC(name, extension, true, "", "", path, parameters)); else { decoder.extension = extension; @@ -545,8 +547,8 @@ return processor.Go(); udcLossless = encoders.GetDefault(extension, true); if (encoderLossy == "" || !encoders.TryGetValue(extension, false, encoderLossy, out udcLossy)) udcLossy = encoders.GetDefault(extension, false); - if (decoder == "" || !decoders.TryGetValue(decoder, out udcDecoder)) - udcDecoder = GetDefaultDecoder(extension); + if (decoder == "" || !decoders.TryGetValue(extension, true, decoder, out udcDecoder)) + udcDecoder = decoders.GetDefault(extension, true); if (!formats.TryGetValue(extension, out format)) formats.Add(extension, new CUEToolsFormat(extension, tagger, allowLossless, allowLossy, allowLossyWav, allowEmbed, false, udcLossless, udcLossy, udcDecoder)); else @@ -605,16 +607,6 @@ return processor.Go(); trackFilenameFormat = "%tracknumber%. %title%"; } - public CUEToolsUDC GetDefaultDecoder(string extension) - { - //|| !config.decoders.TryGetValue(fmt.decoder, out decoder) - CUEToolsUDC result = null; - foreach (KeyValuePair decoder in decoders) - if (decoder.Value.Extension == extension && (result == null || result.priority < decoder.Value.priority)) - result = decoder.Value; - return result; - } - public IWebProxy GetProxy() { IWebProxy proxy = null; diff --git a/CUETools.Processor/CUEToolsUDC.cs b/CUETools.Processor/CUEToolsUDC.cs index 27fe275..7d88ed7 100644 --- a/CUETools.Processor/CUEToolsUDC.cs +++ b/CUETools.Processor/CUEToolsUDC.cs @@ -69,7 +69,7 @@ namespace CUETools.Processor lossless = true; supported_modes = ""; default_mode = ""; - priority = 1; + priority = dec.Priority; path = null; parameters = null; type = dectype; diff --git a/CUETools/frmSettings.Designer.cs b/CUETools/frmSettings.Designer.cs index 6a930c2..f954f41 100644 --- a/CUETools/frmSettings.Designer.cs +++ b/CUETools/frmSettings.Designer.cs @@ -133,7 +133,6 @@ namespace JDP this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tabPage10 = new System.Windows.Forms.TabPage(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); - this.listBoxEncoders = new System.Windows.Forms.ListBox(); this.panel1 = new System.Windows.Forms.Panel(); this.groupBoxExternalEncoder = new System.Windows.Forms.GroupBox(); this.labelEncoderName = new System.Windows.Forms.Label(); @@ -146,15 +145,20 @@ namespace JDP this.labelEncoderExtension = new System.Windows.Forms.Label(); this.buttonEncoderAdd = new System.Windows.Forms.Button(); this.comboBoxEncoderExtension = new System.Windows.Forms.ComboBox(); + this.listBoxEncoders = new System.Windows.Forms.ListBox(); this.tabPage11 = new System.Windows.Forms.TabPage(); - this.comboBoxDecoderExtension = new System.Windows.Forms.ComboBox(); + this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel(); + this.listViewDecoders = new System.Windows.Forms.ListView(); + this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.groupBoxExternalDecoder = new System.Windows.Forms.GroupBox(); this.textBoxDecoderPath = new System.Windows.Forms.TextBox(); this.labelDecoderPath = new System.Windows.Forms.Label(); this.labelDecoderParameters = new System.Windows.Forms.Label(); this.textBoxDecoderParameters = new System.Windows.Forms.TextBox(); - this.listViewDecoders = new System.Windows.Forms.ListView(); - this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.panel2 = new System.Windows.Forms.Panel(); + this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.comboBoxDecoderExtension = new System.Windows.Forms.ComboBox(); this.labelDecoderExtension = new System.Windows.Forms.Label(); this.tabPage4 = new System.Windows.Forms.TabPage(); this.groupBox2 = new System.Windows.Forms.GroupBox(); @@ -209,7 +213,9 @@ namespace JDP this.groupBoxExternalEncoder.SuspendLayout(); this.panel3.SuspendLayout(); this.tabPage11.SuspendLayout(); + this.tableLayoutPanel5.SuspendLayout(); this.groupBoxExternalDecoder.SuspendLayout(); + this.panel2.SuspendLayout(); this.tabPage4.SuspendLayout(); this.groupBox2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericLossyWAVQuality)).BeginInit(); @@ -519,8 +525,8 @@ namespace JDP // // textBoxEncoderModes // - this.textBoxEncoderModes.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "SupportedModesStr", true)); resources.ApplyResources(this.textBoxEncoderModes, "textBoxEncoderModes"); + this.textBoxEncoderModes.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "SupportedModesStr", true)); this.textBoxEncoderModes.Name = "textBoxEncoderModes"; this.toolTip1.SetToolTip(this.textBoxEncoderModes, resources.GetString("textBoxEncoderModes.ToolTip")); // @@ -545,15 +551,15 @@ namespace JDP // // textBoxEncoderPath // - this.textBoxEncoderPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "Path", true)); resources.ApplyResources(this.textBoxEncoderPath, "textBoxEncoderPath"); + this.textBoxEncoderPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "Path", true)); this.textBoxEncoderPath.Name = "textBoxEncoderPath"; this.toolTip1.SetToolTip(this.textBoxEncoderPath, resources.GetString("textBoxEncoderPath.ToolTip")); // // textBoxEncoderParameters // - this.textBoxEncoderParameters.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "Parameters", true)); resources.ApplyResources(this.textBoxEncoderParameters, "textBoxEncoderParameters"); + this.textBoxEncoderParameters.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "Parameters", true)); this.textBoxEncoderParameters.Name = "textBoxEncoderParameters"; this.toolTip1.SetToolTip(this.textBoxEncoderParameters, resources.GetString("textBoxEncoderParameters.ToolTip")); // @@ -588,8 +594,8 @@ namespace JDP // // textBoxEncoderName // - this.textBoxEncoderName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "Name", true)); resources.ApplyResources(this.textBoxEncoderName, "textBoxEncoderName"); + this.textBoxEncoderName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.encodersBindingSource, "Name", true)); this.textBoxEncoderName.Name = "textBoxEncoderName"; this.toolTip1.SetToolTip(this.textBoxEncoderName, resources.GetString("textBoxEncoderName.ToolTip")); // @@ -1077,17 +1083,6 @@ namespace JDP this.tableLayoutPanel4.Controls.Add(this.listBoxEncoders, 0, 0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; // - // listBoxEncoders - // - this.listBoxEncoders.BackColor = System.Drawing.SystemColors.Control; - this.listBoxEncoders.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.listBoxEncoders.DataSource = this.encodersBindingSource; - this.listBoxEncoders.DisplayMember = "FullName"; - resources.ApplyResources(this.listBoxEncoders, "listBoxEncoders"); - this.listBoxEncoders.Name = "listBoxEncoders"; - this.tableLayoutPanel4.SetRowSpan(this.listBoxEncoders, 2); - this.listBoxEncoders.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listBoxEncoders_KeyDown); - // // panel1 // this.panel1.Controls.Add(this.groupBoxExternalEncoder); @@ -1169,30 +1164,63 @@ namespace JDP // // comboBoxEncoderExtension // + resources.ApplyResources(this.comboBoxEncoderExtension, "comboBoxEncoderExtension"); this.comboBoxEncoderExtension.DataBindings.Add(new System.Windows.Forms.Binding("SelectedItem", this.encodersBindingSource, "Extension", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.comboBoxEncoderExtension.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxEncoderExtension.FormattingEnabled = true; - resources.ApplyResources(this.comboBoxEncoderExtension, "comboBoxEncoderExtension"); this.comboBoxEncoderExtension.Name = "comboBoxEncoderExtension"; this.comboBoxEncoderExtension.SelectedIndexChanged += new System.EventHandler(this.comboBoxEncoderExtension_SelectedIndexChanged); // + // listBoxEncoders + // + this.listBoxEncoders.BackColor = System.Drawing.SystemColors.Control; + this.listBoxEncoders.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listBoxEncoders.DataSource = this.encodersBindingSource; + this.listBoxEncoders.DisplayMember = "FullName"; + resources.ApplyResources(this.listBoxEncoders, "listBoxEncoders"); + this.listBoxEncoders.Name = "listBoxEncoders"; + this.tableLayoutPanel4.SetRowSpan(this.listBoxEncoders, 2); + this.listBoxEncoders.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listBoxEncoders_KeyDown); + // // tabPage11 // this.tabPage11.BackColor = System.Drawing.SystemColors.Control; - this.tabPage11.Controls.Add(this.comboBoxDecoderExtension); - this.tabPage11.Controls.Add(this.groupBoxExternalDecoder); - this.tabPage11.Controls.Add(this.listViewDecoders); - this.tabPage11.Controls.Add(this.labelDecoderExtension); + this.tabPage11.Controls.Add(this.tableLayoutPanel5); resources.ApplyResources(this.tabPage11, "tabPage11"); this.tabPage11.Name = "tabPage11"; // - // comboBoxDecoderExtension + // tableLayoutPanel5 // - this.comboBoxDecoderExtension.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxDecoderExtension.FormattingEnabled = true; - resources.ApplyResources(this.comboBoxDecoderExtension, "comboBoxDecoderExtension"); - this.comboBoxDecoderExtension.Name = "comboBoxDecoderExtension"; - this.comboBoxDecoderExtension.SelectedIndexChanged += new System.EventHandler(this.comboBoxDecoderExtension_SelectedIndexChanged); + resources.ApplyResources(this.tableLayoutPanel5, "tableLayoutPanel5"); + this.tableLayoutPanel5.Controls.Add(this.groupBoxExternalDecoder, 1, 1); + this.tableLayoutPanel5.Controls.Add(this.panel2, 1, 0); + this.tableLayoutPanel5.Controls.Add(this.listViewDecoders, 0, 0); + this.tableLayoutPanel5.Name = "tableLayoutPanel5"; + // + // listViewDecoders + // + this.listViewDecoders.BackColor = System.Drawing.SystemColors.Control; + this.listViewDecoders.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listViewDecoders.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader4}); + this.listViewDecoders.FullRowSelect = true; + this.listViewDecoders.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + this.listViewDecoders.HideSelection = false; + this.listViewDecoders.LabelEdit = true; + resources.ApplyResources(this.listViewDecoders, "listViewDecoders"); + this.listViewDecoders.MultiSelect = false; + this.listViewDecoders.Name = "listViewDecoders"; + this.tableLayoutPanel5.SetRowSpan(this.listViewDecoders, 2); + this.listViewDecoders.UseCompatibleStateImageBehavior = false; + this.listViewDecoders.View = System.Windows.Forms.View.Details; + this.listViewDecoders.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listViewDecoders_AfterLabelEdit); + this.listViewDecoders.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listViewDecoders_BeforeLabelEdit); + this.listViewDecoders.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.listViewDecoders_ItemSelectionChanged); + this.listViewDecoders.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listViewDecoders_KeyDown); + // + // columnHeader4 + // + resources.ApplyResources(this.columnHeader4, "columnHeader4"); // // groupBoxExternalDecoder // @@ -1224,29 +1252,35 @@ namespace JDP resources.ApplyResources(this.textBoxDecoderParameters, "textBoxDecoderParameters"); this.textBoxDecoderParameters.Name = "textBoxDecoderParameters"; // - // listViewDecoders + // panel2 // - this.listViewDecoders.BackColor = System.Drawing.SystemColors.Control; - this.listViewDecoders.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.listViewDecoders.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeader4}); - this.listViewDecoders.FullRowSelect = true; - this.listViewDecoders.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; - this.listViewDecoders.HideSelection = false; - this.listViewDecoders.LabelEdit = true; - resources.ApplyResources(this.listViewDecoders, "listViewDecoders"); - this.listViewDecoders.MultiSelect = false; - this.listViewDecoders.Name = "listViewDecoders"; - this.listViewDecoders.UseCompatibleStateImageBehavior = false; - this.listViewDecoders.View = System.Windows.Forms.View.Details; - this.listViewDecoders.AfterLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listViewDecoders_AfterLabelEdit); - this.listViewDecoders.BeforeLabelEdit += new System.Windows.Forms.LabelEditEventHandler(this.listViewDecoders_BeforeLabelEdit); - this.listViewDecoders.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.listViewDecoders_ItemSelectionChanged); - this.listViewDecoders.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listViewDecoders_KeyDown); + this.panel2.Controls.Add(this.button2); + this.panel2.Controls.Add(this.button1); + this.panel2.Controls.Add(this.comboBoxDecoderExtension); + this.panel2.Controls.Add(this.labelDecoderExtension); + resources.ApplyResources(this.panel2, "panel2"); + this.panel2.Name = "panel2"; // - // columnHeader4 + // button2 // - resources.ApplyResources(this.columnHeader4, "columnHeader4"); + this.button2.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.encodersBindingSource, "CanBeDeleted", true)); + resources.ApplyResources(this.button2, "button2"); + this.button2.Name = "button2"; + this.button2.UseVisualStyleBackColor = true; + // + // button1 + // + resources.ApplyResources(this.button1, "button1"); + this.button1.Name = "button1"; + this.button1.UseVisualStyleBackColor = true; + // + // comboBoxDecoderExtension + // + resources.ApplyResources(this.comboBoxDecoderExtension, "comboBoxDecoderExtension"); + this.comboBoxDecoderExtension.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxDecoderExtension.FormattingEnabled = true; + this.comboBoxDecoderExtension.Name = "comboBoxDecoderExtension"; + this.comboBoxDecoderExtension.SelectedIndexChanged += new System.EventHandler(this.comboBoxDecoderExtension_SelectedIndexChanged); // // labelDecoderExtension // @@ -1476,9 +1510,11 @@ namespace JDP this.panel3.ResumeLayout(false); this.panel3.PerformLayout(); this.tabPage11.ResumeLayout(false); - this.tabPage11.PerformLayout(); + this.tableLayoutPanel5.ResumeLayout(false); this.groupBoxExternalDecoder.ResumeLayout(false); this.groupBoxExternalDecoder.PerformLayout(); + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); this.tabPage4.ResumeLayout(false); this.tabPage4.PerformLayout(); this.groupBox2.ResumeLayout(false); @@ -1640,6 +1676,10 @@ namespace JDP private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button1; } } \ No newline at end of file diff --git a/CUETools/frmSettings.cs b/CUETools/frmSettings.cs index 880689c..edc67da 100644 --- a/CUETools/frmSettings.cs +++ b/CUETools/frmSettings.cs @@ -116,11 +116,11 @@ namespace JDP if (comboLanguage.SelectedItem == null) comboLanguage.SelectedItem = comboLanguage.Items[0]; - foreach (KeyValuePair decoder in _config.decoders) - if (decoder.Value.path != null) + foreach (var decoder in _config.decoders) + if (decoder.path != null) { - ListViewItem item = new ListViewItem(decoder.Key); - item.Tag = decoder.Value; + ListViewItem item = new ListViewItem(decoder.Name); + item.Tag = decoder; listViewDecoders.Items.Add(item); } //listViewDecoders.Items[0].Selected = true; @@ -326,13 +326,13 @@ namespace JDP return; } - foreach (CUEToolsUDC encoder in _config.encoders) + foreach (var encoder in _config.encoders) if (encoder.extension == format.extension) encoder.extension = e.Label; - foreach (KeyValuePair decoder in _config.decoders) - if (decoder.Value.extension == format.extension) - decoder.Value.extension = e.Label; + foreach (var decoder in _config.decoders) + if (decoder.extension == format.extension) + decoder.extension = e.Label; comboBoxEncoderExtension.Items.Remove(format.extension); comboBoxEncoderExtension.Items.Add(e.Label); @@ -370,15 +370,15 @@ namespace JDP CUEToolsFormat format = (CUEToolsFormat)listViewFormats.SelectedItems[0].Tag; if (format.builtin) return; - List decodersToRemove = new List(); - foreach (KeyValuePair decoder in _config.decoders) - if (decoder.Value.extension == format.extension) - decodersToRemove.Add(decoder.Key); - foreach (string decoder in decodersToRemove) + var decodersToRemove = new List(); + foreach (var decoder in _config.decoders) + if (decoder.extension == format.extension) + decodersToRemove.Add(decoder); + foreach (var decoder in decodersToRemove) { _config.decoders.Remove(decoder); foreach (ListViewItem item in listViewDecoders.Items) - if (item.Text == decoder) + if (item.Tag == decoder) { item.Remove(); break; @@ -422,9 +422,9 @@ namespace JDP comboFormatLossyEncoder.Enabled = format.allowLossy; comboFormatDecoder.Items.Clear(); - foreach (KeyValuePair decoder in _config.decoders) - if (decoder.Value.extension == format.extension) - comboFormatDecoder.Items.Add(decoder.Value); + foreach (var decoder in _config.decoders) + if (decoder.extension == format.extension) + comboFormatDecoder.Items.Add(decoder); comboFormatDecoder.SelectedItem = format.decoder; comboFormatDecoder.Enabled = format.allowLossless; @@ -579,18 +579,15 @@ namespace JDP private void listViewDecoders_AfterLabelEdit(object sender, LabelEditEventArgs e) { - CUEToolsUDC decoder; - if (e.Label == null || _config.decoders.TryGetValue(e.Label, out decoder)) + if (e.Label == null) { e.CancelEdit = true; return; } - decoder = (CUEToolsUDC)listViewDecoders.Items[e.Item].Tag; - if (listViewFormats.SelectedItems.Count > 0) + var decoder = listViewDecoders.Items[e.Item].Tag as CUEToolsUDC; + if (listViewFormats.SelectedItems.Count > 0) listViewFormats.SelectedItems[0].Selected = false; - _config.decoders.Remove(decoder.name); decoder.name = e.Label; - _config.decoders.Add(decoder.name, decoder); } private void listViewDecoders_BeforeLabelEdit(object sender, LabelEditEventArgs e) @@ -606,11 +603,8 @@ namespace JDP { case Keys.Insert: { - CUEToolsUDC decoder; - if (_config.decoders.TryGetValue("new", out decoder)) - return; - decoder = new CUEToolsUDC("new", "wav", true, "", "", "", ""); - _config.decoders.Add("new", decoder); + var decoder = new CUEToolsUDC("new", "wav", true, "", "", "", ""); + _config.decoders.Add(decoder); ListViewItem item = new ListViewItem(decoder.name); item.Tag = decoder; listViewDecoders.Items.Add(item); @@ -621,12 +615,12 @@ namespace JDP { if (listViewDecoders.SelectedItems.Count <= 0) return; - CUEToolsUDC decoder = (CUEToolsUDC)listViewDecoders.SelectedItems[0].Tag; + CUEToolsUDC decoder = listViewDecoders.SelectedItems[0].Tag as CUEToolsUDC; if (decoder.path == null) return; if (_config.formats[decoder.extension].decoder == decoder) _config.formats[decoder.extension].decoder = null; - _config.decoders.Remove(decoder.name); + _config.decoders.Remove(decoder); listViewDecoders.Items.Remove(listViewDecoders.SelectedItems[0]); break; } diff --git a/CUETools/frmSettings.resx b/CUETools/frmSettings.resx index e188a66..f03f7f9 100644 --- a/CUETools/frmSettings.resx +++ b/CUETools/frmSettings.resx @@ -1122,6 +1122,9 @@ 8 + + Top, Left, Right + 575, 17 @@ -1129,10 +1132,10 @@ 251, 17 - 96, 80 + 96, 78 - 262, 21 + 287, 21 27 @@ -1165,7 +1168,7 @@ NoControl - 301, 115 + 314, 109 65, 17 @@ -1191,11 +1194,14 @@ 5 + + Top, Left, Right + 96, 20 - 262, 21 + 287, 21 14 @@ -1215,11 +1221,14 @@ 2 + + Top, Left, Right + 96, 49 - 262, 21 + 287, 21 16 @@ -1371,11 +1380,14 @@ 0 + + Top, Left, Right + - 96, 111 + 96, 107 - 191, 21 + 212, 21 28 @@ -2952,6 +2964,9 @@ 2 + + Top, Left, Right + None @@ -2959,7 +2974,7 @@ True - 6, 114 + 6, 110 34, 13 @@ -2989,7 +3004,7 @@ NoControl - 6, 83 + 6, 81 38, 13 @@ -3072,14 +3087,11 @@ 8 - - Fill - 0, 0 - 398, 235 + 394, 235 22 @@ -3109,7 +3121,7 @@ 0, 0 - 398, 235 + 394, 236 31 @@ -3130,10 +3142,10 @@ Fill - 128, 47 + 132, 46 - 398, 235 + 394, 236 32 @@ -3171,7 +3183,7 @@ NoControl - 34, 6 + 42, 7 25, 23 @@ -3191,6 +3203,9 @@ 0 + + Top, Right + True @@ -3201,7 +3216,7 @@ NoControl - 222, 6 + 208, 10 100, 16 @@ -3248,7 +3263,7 @@ - 3, 6 + 9, 7 25, 23 @@ -3268,8 +3283,11 @@ 2 + + Top, Right + - 328, 3 + 316, 7 67, 21 @@ -3296,10 +3314,10 @@ Fill - 128, 3 + 132, 3 - 398, 38 + 394, 37 34 @@ -3323,7 +3341,7 @@ 3, 3 - 119, 279 + 123, 279 27 @@ -3368,7 +3386,7 @@ 0 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="panel1" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="panel3" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="listBoxEncoders" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,23.62949,Percent,76.37051" /><Rows Styles="Percent,15.44715,Percent,84.55285" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="panel1" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="panel3" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="listBoxEncoders" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,24.38563,Percent,75.61436" /><Rows Styles="Percent,15.08772,Percent,84.91228" /></TableLayoutSettings> 4, 22 @@ -3397,35 +3415,17 @@ 4 - - 459, 12 + + 2 - - 67, 21 - - - 28 - - - False - - - comboBoxDecoderExtension - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPage11 - - - 0 + + Top, Left, Right 96, 20 - 262, 21 + 287, 21 21 @@ -3479,7 +3479,7 @@ NoControl - 6, 50 + 6, 52 62, 13 @@ -3502,11 +3502,14 @@ 2 + + Top, Left, Right + - 96, 47 + 96, 49 - 262, 21 + 287, 21 23 @@ -3523,11 +3526,14 @@ 3 + + Fill + - 136, 39 + 132, 44 - 390, 87 + 394, 238 27 @@ -3545,35 +3551,129 @@ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tabPage11 + tableLayoutPanel5 + 0 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACaUlEQVQ4T6WT+0tTYRjH/Vv0hyhBohsh + YRQU5rzMnbU2t3k7y/S4xSKWpuwM0wxqGLrwh3CW2lUrf8k0sVFeMnJ2HVoeKy/t1Eat6Tm7pnzbJm0u + RxC98HnhPDyf78t5znmTAPwXGwoLGk3KPFWp/0CVM7MqkptRlXDvSSUzRcr1tlJpyp/9cQ+Lag3xiaLY + 76Ym+EcsCLy1IjAxCv5+Nxa0ZXhdSLAvlEJivRMnz1VQ/PLdbqzOvkNw8B6CXc0Imi/g5+02rIwPwlGr + hVWezT+XZkZDItu8Wp0cku3czS6sMjYEL5+Du9mApaYa+C8ZEGih4Teegv/BLSweJzF+5IB9TLIvORoQ + kmlnvR4rtsnIiT4TDdd5HbwN6ji40yT8vdfwKi8Dw+IMOhrwkTrGeHqvI9hjhttYhW9F4oQsV5Hgm+rg + MFTjMZHORAOYCpU38LAXQZMB7rPaUCnxcshy4KIKsWRuhSVvlzdUWguYIYu8vp4O+Bu18J4pjzQnWuEA + Z5kCS22tGBJuiwVMlyoYl7EOvmYa3EllpDEh8jy462uxUKvDoCAt9gq2YinNSATw9nTCrZLAVSbaILPS + bLAFIni6rmBUuAMDWVtiQ3xTJE5+WULYFytL4LnTERmYUyFcE2W5YCUhWSIE39mOqWJxWLb3CTbHPmOY + yYIcYkJ2iJ87qoDnRgd+NNJwkHJ8UcrgatCDv9qOaWU++rNS+ZAc/yP95pn0IPH08H7WKtqDrzU6uFou + RvhcfQJPcraHZXa9HCYuIMyIeG/KsDBdbyF2M4/yd3JDgq3cQG4a05+dqu/L3PT3y/TvIOkXHdLOuWlI + 1ksAAAAASUVORK5CYII= + + + + NoControl + + + 42, 7 + + + 25, 23 + + + 30 + + + False + + + button2 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel2 + + + 0 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAChUlEQVQ4T6WT/UtTURzG/Vv0lwIhKTEL + BTWlBAtlZbNNVHSaLudsis52N5fOuc0XMp0bvlTUhm6jkW7TOR2+YCZOLV2kXocSbRRBUBv++nTPhk5N + guiB58D9fs/nufece04MgP/yHwWNqy6u3VlLtToEdPN4VVDypiLY8LqUFpmLKcEIN+70/BMPGpeIpZys + Dbxa68VKYAHe7+tY+7aMSZ8VMmc1Kg3sAO/FbdZx5hQsDLl2rdj/tYuZLw4Y6AE839bCumfA4tdZqOfF + KBrODXEGco5CwoN6ShTLwP6JHRN2f25haKsHT1fb0eVphdarQZ9Xja6NFkzsW0E5+cjX3fDn9WbGHgUw + sLR/SYFPPzaYN/ahd1MN1TsZ04pIsSqGZIEP6VIN7HsW3B3OQs6TNCnTigS02Ktph8/CfKoRHStytC1L + IJ4RhGGiKgsHDdPFEE1xof+gQc9iM653pdBMKxIgHas8cH92oP+jhoGbwtBZEk4WQDpXCZN3CBma5AOm + FAlosvIOxn2jUK9TkHvqw5PPEgmg3BUweweR2p4YDai3lNA6jxraTRWa3vIhnCsFz3wnDBERkPihk4N+ + jwKd7ke4okiILkE4Wii9b2bB5jNBPFeGWndReM2HIrDAzkbdBBe2HSOudScj8XF8dBP5xoLY8pf5fspZ + hTF65GjDCFhjJyYwB+PbBjww3SOwP0F2PvobiUue5bEKB2+GGm1lsDMhOo8S1HQ5JFNl0K20wcbAfBMb + ifL4EAOfPEiHZuuzWSxtViBXn47ueQrG91oY17VQuRuR0ZlE4MBxmPhEAPGtnvS47O5UKrPjKp2mSgqm + KC8GL7deoC/J46kE2bm/X6Z/N2J+A0FGyx8pOKmLAAAAAElFTkSuQmCC + + + + NoControl + + + 9, 7 + + + 25, 23 + + + 29 + + + False + + + button1 + + + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel2 + + 1 - - 120 + + Top, Right - - 3, 6 + + 316, 7 - - 124, 279 + + 67, 21 - - 26 + + 28 - - listViewDecoders + + False - - System.Windows.Forms.ListView, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + comboBoxDecoderExtension - - tabPage11 + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + panel2 + + 2 + + Top, Right + True @@ -3584,7 +3684,7 @@ NoControl - 351, 15 + 208, 10 100, 16 @@ -3608,11 +3708,89 @@ System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tabPage11 + panel2 3 + + Fill + + + 132, 3 + + + 394, 35 + + + 28 + + + panel2 + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel5 + + + 1 + + + 120 + + + 3, 3 + + + 123, 279 + + + 26 + + + listViewDecoders + + + System.Windows.Forms.ListView, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel5 + + + 2 + + + Fill + + + 3, 3 + + + 2 + + + 529, 285 + + + 29 + + + tableLayoutPanel5 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tabPage11 + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="groupBoxExternalDecoder" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="panel2" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="listViewDecoders" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,24.38563,Percent,75.61436" /><Rows Styles="Percent,14.73684,Percent,85.26316" /></TableLayoutSettings> + 4, 22