},\r
OutputFormat = "{0}_{1}_{2}"\r
};\r
- //todo utolsó paraméterként szegmens lista átadása\r
- FTPTargetProcessor sut = new FTPTargetProcessor(null, null, configuration, @"c:\tmp\watch\tcdrone.MXF", "000000", null);\r
+ FTPTargetProcessor sut = new FTPTargetProcessor(null, null, configuration, @"c:\tmp\watch\tcdrone.MXF", "000000", null, null, null);\r
sut.Execute();\r
}\r
\r
this.button_cancel.TabIndex = 0;\r
this.button_cancel.Text = "Cancel";\r
this.button_cancel.UseVisualStyleBackColor = true;\r
+ this.button_cancel.Click += new System.EventHandler(this.button_cancel_Click);\r
// \r
// button_ok\r
// \r
}\r
\r
private void button_ok_Click(object sender, System.EventArgs e) {\r
- //todo\r
+ model.StuffID = textBox_stuffID.Text;\r
+ model.StuffTitle = textBox_stuffTitle.Text;\r
+ model.StuffDescription = textBox_stuffDescription.Text;\r
+ model.MediaID = textBox_mediaID.Text;\r
+ model.MediaTitle = textBox_mediaTitle.Text;\r
+ model.MediaDescription = textBox_mediaDescription.Text;\r
+ Dispose();\r
+ }\r
+\r
+ private void button_cancel_Click(object sender, System.EventArgs e) {\r
+ Dispose();\r
}\r
}\r
}\r
public bool SaveSegments { get; set; }\r
public bool CreateSubFolder { get; set; }\r
public string Tag { get; set; }\r
+ public bool UseMetadata {get; set;}\r
}\r
\r
public class Connection {\r
using System.ComponentModel;\r
using System.Text.RegularExpressions;\r
using JobEngineClient;\r
+\r
namespace Maestro {\r
public partial class MaestroForm {\r
private MetadataInfo selectedMetadata;\r
private List<Segment> segments = new List<Segment>();\r
private MediaCubeApi mediaCubeApi;\r
-\r
+ private ArchiveMetadataModel model;\r
public MetadataInfo SelectedMetadata {\r
get {\r
return selectedMetadata;\r
}\r
\r
private void ModifyArchiveMetadataClick(object sender, EventArgs e) {\r
- ArchiveMetadata form = null;\r
- IDTypes idType = GetTypeOfSelectedMetadata();\r
- ArchiveMetadataModel model = new ArchiveMetadataModel();\r
- Cursor.Current = Cursors.WaitCursor;\r
- if (idType == IDTypes.OctopusID)\r
- FillTheModelFromOctopus(model);\r
- else if (idType == IDTypes.TrafficID)\r
- FillTheModelFromTraffic(model);\r
- form = new ArchiveMetadata(model);\r
+ ArchiveMetadata form = new ArchiveMetadata(model);\r
form.ShowDialog();\r
}\r
\r
- private void FillTheModelFromTraffic(ArchiveMetadataModel model) {\r
- string id = selectedMetadata.ID;\r
- TrafficAPI api = trafficIDSelector.trafficAPI;\r
- List<ArchiveMatadataWrapper> result = api.SearchArchiveMetadata(id); ;\r
- ArchiveMatadataWrapper actualResult = result[0];\r
- model.StuffID = actualResult.ProgID;\r
- model.StuffTitle = actualResult.ProgTitle;\r
- model.StuffDescription = actualResult.ProgDescription;\r
- model.MediaID = actualResult.EpisodeID;\r
- model.MediaTitle = String.IsNullOrEmpty(actualResult.EpisodeTitle) ? actualResult.EpisodeTitle : actualResult.ProgTitle;\r
- model.MediaDescription = actualResult.EpisodeDescription;\r
- }\r
-\r
- private void FillTheModelFromOctopus(ArchiveMetadataModel model) {\r
- string id = selectedMetadata.ID;\r
- OctopusAPI api = octopusIDSelector.GetClient();\r
- IEnumerable<Story> storyEnum = api.GetStoriesById(id);\r
- if (storyEnum != null) {\r
- FillModelFromStories(model, storyEnum.ToList(), api);\r
- } else {\r
- //List<MosObject> mosObjectsEnum = api.GetMosObjectsByID(id).ToList();\r
- //MosObject mosObject = mosObjectsEnum[0];\r
- List<Story> stories = api.GetStoriesByPlaceHolderId(id).ToList();\r
- FillModelFromStories(model, stories, api);\r
- //todo ha mosObject, mivel töltsem fel a model-t?\r
- }\r
- }\r
-\r
- private void FillModelFromStories(ArchiveMetadataModel model, List<Story> stories, OctopusAPI api) {\r
- Story story = stories[0];\r
- if (story.StoryFolders != null) {\r
- List<StoryFolder> storyFolders = api.GetStoryFoldersByStoryID(story.ID).ToList();\r
- StoryFolder folder = storyFolders[0];\r
- model.StuffID = folder.ID;\r
- model.StuffTitle = folder.Name;\r
- } else if (story.Rundowns != null) {\r
- List<Rundown> rundowns = api.GetRundownsByStoryID(story.ID).ToList();\r
- Rundown rundown = rundowns[0];\r
- model.StuffID = rundown.ID;\r
- model.StuffTitle = rundown.Name;\r
- model.StuffDescription = rundown.Start;\r
- }\r
- model.MediaID = story.ID;\r
- model.MediaTitle = story.Name;\r
- model.MediaDescription = story.Script;\r
- }\r
+ \r
\r
private IDTypes GetTypeOfSelectedMetadata() {\r
IDTypes result = IDTypes.None;\r
}\r
\r
private void SetSelectedSourceFileInfo(SourceInfo selectedSource) {\r
- //todo ha nexio-s akkor null a fileinfo\r
- if (selectedSources.Count == 1) {\r
+ if (Configuration.Source.GetType() == typeof(NEXIOSource))\r
+ selectedSource.FileInfo = null;\r
+ else if (selectedSources.Count == 1) {\r
Uri inputUri = new Uri(String.Format("{0}/{1}", Configuration.Source.Local.Address.LocalPath, selectedSources[0]));\r
selectedSource.FileInfo = new System.IO.FileInfo(inputUri.LocalPath);\r
}\r
using System.Collections.Generic;\r
using System.Text.RegularExpressions;\r
using TrafficClient;\r
+using OctopusClient;\r
\r
namespace Maestro {\r
public partial class MaestroForm {\r
foreach (String actual in selectedSources) {\r
string typeName = string.Format("{0}.{1}", typeof(ITargetProcessor).Namespace, target.Processor);\r
Type type = Type.GetType(typeName);\r
-\r
- //ISourceItem actualFile = new FileSourceItem() { FileInfo = new System.IO.FileInfo(actual), };\r
ISourceItem selectedFile = GetSourceItemFromBindingSource(actual);//bindingSource.Current as ISourceItem;\r
string id = selectedMetadata.ID;\r
- object[] parameters = new object[] { this, Configuration.Source, target, selectedFile.Name, id, segments, mediaCubeApi };\r
+ object[] parameters = new object[] { this, Configuration.Source, target, selectedFile.Name, id, segments, mediaCubeApi, model };\r
ITargetProcessor processor = (ITargetProcessor)Activator.CreateInstance(type, parameters);\r
processors.Add(processor);\r
}\r
currentProcessors.Add(checkBox, processors);\r
} else\r
currentProcessors.Remove(checkBox);\r
-\r
btnExecute.Enabled = currentProcessors.Count > 0;\r
};\r
\r
ChangeProcessButtonsState(false);\r
}\r
\r
- ctxiModifyArchiveMetadata.Enabled = selectedMetadata != null;\r
-\r
if (Configuration.Player != null)\r
ctxiDefineSegments.Enabled = SelectedSource?.FileInfo != null && Configuration.Player.SegmentEditor && MetadataType.Traffic.Equals(SelectedMetadata?.Kind);\r
IsSelectedFileAnID();\r
+ EnableArchiveMetadataButtonAndCreateMetadataModel();\r
+ }\r
+\r
+ private void EnableArchiveMetadataButtonAndCreateMetadataModel() {\r
+ ctxiModifyArchiveMetadata.Enabled = selectedMetadata != null;\r
+ if (ctxiModifyArchiveMetadata.Enabled) {\r
+ model = new ArchiveMetadataModel();\r
+ Cursor.Current = Cursors.WaitCursor;\r
+ IDTypes idType = GetTypeOfSelectedMetadata();\r
+ if (idType == IDTypes.OctopusID)\r
+ FillTheModelFromOctopus(model);\r
+ else if (idType == IDTypes.TrafficID)\r
+ FillTheModelFromTraffic(model);\r
+ } else\r
+ model = null;\r
+ }\r
+\r
+ private void FillTheModelFromTraffic(ArchiveMetadataModel model) {\r
+ string id = selectedMetadata.ID;\r
+ TrafficAPI api = trafficIDSelector.trafficAPI;\r
+ List<ArchiveMatadataWrapper> result = api.SearchArchiveMetadata(id); ;\r
+ ArchiveMatadataWrapper actualResult = result[0];\r
+ model.StuffID = actualResult.ProgID;\r
+ model.StuffTitle = actualResult.ProgTitle;\r
+ model.StuffDescription = actualResult.ProgDescription;\r
+ model.MediaID = actualResult.EpisodeID;\r
+ model.MediaTitle = String.IsNullOrEmpty(actualResult.EpisodeTitle) ? actualResult.EpisodeTitle : actualResult.ProgTitle;\r
+ model.MediaDescription = actualResult.EpisodeDescription;\r
+ }\r
+\r
+ private void FillTheModelFromOctopus(ArchiveMetadataModel model) {\r
+ string id = selectedMetadata.ID;\r
+ OctopusAPI api = octopusIDSelector.GetClient();\r
+ IEnumerable<Story> storyEnum = api.GetStoriesById(id);\r
+ if (storyEnum != null) \r
+ FillModelFromStories(model, storyEnum.ToList(), api);\r
+ else {\r
+ List<Story> stories = api.GetStoriesByPlaceHolderId(id).ToList();\r
+ FillModelFromStories(model, stories, api);\r
+ }\r
+ }\r
+\r
+ private void FillModelFromStories(ArchiveMetadataModel model, List<Story> stories, OctopusAPI api) {\r
+ Story story = stories[0];\r
+ if (story.StoryFolders != null) {\r
+ List<StoryFolder> storyFolders = api.GetStoryFoldersByStoryID(story.ID).ToList();\r
+ StoryFolder folder = storyFolders[0];\r
+ model.StuffID = folder.ID;\r
+ model.StuffTitle = folder.Name;\r
+ } else if (story.Rundowns != null) {\r
+ List<Rundown> rundowns = api.GetRundownsByStoryID(story.ID).ToList();\r
+ Rundown rundown = rundowns[0];\r
+ model.StuffID = rundown.ID;\r
+ model.StuffTitle = rundown.Name;\r
+ model.StuffDescription = rundown.Start;\r
+ }\r
+ model.MediaID = story.ID;\r
+ model.MediaTitle = story.Name;\r
+ model.MediaDescription = story.Script;\r
}\r
\r
private void IsSelectedFileAnID() {\r
public string MediaID { get; set; }\r
public string MediaTitle { get; set; }\r
public string MediaDescription { get; set; }\r
+\r
+ public override string ToString() {\r
+ return String.Format("{{\n \"Anyag azonosító\": \"{0}\",\n, \"Anyag cím\": \"{1}\",\n \"Anyag leírása\": \"{2}\",\n \"Média azonosító\": \"{3}\",\n \"Média cím\": \"{4}\",\n \"Média leírás\": \"{5}\" \n}}",\r
+ StuffID, StuffTitle, StuffDescription, MediaID, MediaTitle, MediaDescription);\r
+ }\r
}\r
}\r
"killDateDays": 1,\r
"tag": "tag",\r
"createSubFolder": true,\r
+ "useMetadata": true,\r
"remote": {\r
"address": "ftp://localhost:21/out",\r
"userName": "dani",\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Looks up a localized string similar to Archive.\r
+ /// </summary>\r
+ internal static string ARCHIVE {\r
+ get {\r
+ return ResourceManager.GetString("ARCHIVE", resourceCulture);\r
+ }\r
+ }\r
+ \r
/// <summary>\r
/// Looks up a localized string similar to Befejezés.\r
/// </summary>\r
<data name="ALLAPOT" xml:space="preserve">\r
<value>Állapot</value>\r
</data>\r
+ <data name="ARCHIVE" xml:space="preserve">\r
+ <value>Archive</value>\r
+ </data>\r
<data name="ARCHÍV_METAADATOK_MODOSITASA" xml:space="preserve">\r
<value>Archív metaadatok módosítása</value>\r
</data>\r
using TrafficClient;\r
using Model;\r
using JobEngineClient;\r
+using Maestro.Metadata;\r
\r
namespace Maestro.Targets {\r
\r
\r
public WorkflowAction workFlowAction { get; set; }\r
\r
- public FTPTargetProcessor(Control parent, Source sourceConfig, Target targetConfig, string inputFileName, string id, List<Segment> segments, MediaCubeApi mediaCubeApi) : base(parent, targetConfig, segments) {\r
+ public FTPTargetProcessor(Control parent, Source sourceConfig, Target targetConfig, string inputFileName, string id, List<Segment> segments, MediaCubeApi mediaCubeApi, ArchiveMetadataModel model)\r
+ : base(parent, targetConfig, segments, model) {\r
FtpTrace.LogFunctions = false;\r
this.mediaCubeApi = mediaCubeApi;\r
this.targetConfig = targetConfig;\r
Uri inputUri = new Uri(String.Format("{0}/{1}", sourceConfig.Local.Address.LocalPath, inputFileName));\r
- inputFile = new FileInfo(inputUri.LocalPath); \r
+ inputFile = new FileInfo(inputUri.LocalPath);\r
Input = inputFile.FullName;\r
ID = id;\r
workFlowAction = new WorkflowAction() { houseId = ID, tag = targetConfig.Tag, touched = DateTime.Now };\r
try {\r
SetSubFolder(targetConfig.Remote);\r
targetFTP = CreateClient(targetConfig.Remote);\r
- EnsureDirectoryExistence(targetFTP);\r
+ EnsureDirectoryExistence(targetFTP, workingDir);\r
Status = ProcessStatus.Progress;\r
Output = CreateOutputFileName();\r
workFlowAction.destination = Path.Combine(workingDir, Output).Replace("\\", "/");\r
UploadFile(Output);\r
if (targetConfig.KillDateDays > 0)\r
UploadKillDateFile(targetConfig.Remote, Output);\r
+ if (targetConfig.UseMetadata)\r
+ UseMetadata();\r
ExecuteCompleted();\r
Status = ProcessStatus.Completed;\r
Message = SUCCESS;\r
return result;\r
}\r
\r
+ private void UseMetadata() {\r
+ if (model != null) {\r
+ string path = String.Format("{0}//.store", workingDir);\r
+ string fileName = "metadata.json";\r
+ EnsureDirectoryExistence(targetFTP, path);\r
+ string finalFileName = GetVersionedFileName(fileName);\r
+ using (Stream ostream = targetFTP.OpenWrite(finalFileName)) {\r
+ string s = model.ToString();\r
+ byte[] content = System.Text.Encoding.UTF8.GetBytes(s);\r
+ ostream.Write(content, 0, content.Length);\r
+ }\r
+ }\r
+ }\r
+\r
+ private string GetVersionedFileName(string fileName) {\r
+ string result = fileName;\r
+ string nameWithoutExtension = String.Format(Path.GetFileNameWithoutExtension(fileName));\r
+ string extension = Path.GetExtension(fileName);\r
+ int version = 0;\r
+ while (targetFTP.FileExists(result)) {\r
+ string versioned = String.Format(VERSIONED_FILENAME, nameWithoutExtension, version, extension);\r
+ logger.Debug(ALREADY_EXISTS, result, versioned);\r
+ result = versioned;\r
+ version++;\r
+ }\r
+ return result;\r
+ }\r
+\r
private void SendWorkFlowAction() {\r
try {\r
mediaCubeApi.Create(workFlowAction);\r
- } catch (Exception e) {\r
- MessageBox.Show(parent , e.Message);\r
+ }\r
+ catch (Exception e) {\r
+ MessageBox.Show(parent, e.Message);\r
}\r
}\r
\r
private void UploadKillDateFile(Connection connection, string output) {\r
Uri address = connection.Address;\r
string statusWorkDir = Path.Combine(address.PathAndQuery, STATUS_FOLDER).Replace("\\", "/");\r
- EnsureDirectoryExistence(targetFTP);\r
+ EnsureDirectoryExistence(targetFTP, workingDir);\r
DateTime date = DateTime.Now;\r
date = date.AddDays(targetConfig.KillDateDays);\r
string fileName = String.Format(KILLDATE_FILE, output, date.ToString("yyyyMMdd"));\r
}\r
\r
\r
- private void EnsureDirectoryExistence(FtpClient client) {\r
- if (!client.DirectoryExists(workingDir))\r
- client.CreateDirectory(workingDir, true);\r
- client.SetWorkingDirectory(workingDir);\r
+ private void EnsureDirectoryExistence(FtpClient client, string path) {\r
+ if (!client.DirectoryExists(path))\r
+ client.CreateDirectory(path, true);\r
+ client.SetWorkingDirectory(path);\r
}\r
\r
protected FtpClient CreateClient(Connection connection) {\r
using System.Collections.Generic;\r
using TrafficClient;\r
using JobEngineClient;\r
+using Maestro.Metadata;\r
\r
namespace Maestro.Targets {\r
\r
private Logger logger = LogManager.GetCurrentClassLogger();\r
private Source sourceConfig;\r
\r
- public FXPTargetProcessor(Control parent, Source sourceConfig, Target targetConfig, string inputFileName, string id, List<Segment> segments, MediaCubeApi mediaCubeApi ) :\r
- base(parent, sourceConfig, targetConfig, inputFileName, id, segments, mediaCubeApi) {\r
+ public FXPTargetProcessor(Control parent, Source sourceConfig, Target targetConfig, string inputFileName, string id, List<Segment> segments, MediaCubeApi mediaCubeApi, ArchiveMetadataModel model) :\r
+ base(parent, sourceConfig, targetConfig, inputFileName, id, segments, mediaCubeApi, model) {\r
this.sourceConfig = sourceConfig;\r
}\r
\r
using System.Collections.Generic;\r
using Maestro.Configuration;\r
using TrafficClient;\r
-using DxPlay;\r
+using Maestro.Metadata;\r
\r
namespace Maestro.Targets {\r
public abstract class TargetProcessor : ITargetProcessor {\r
protected Target targetConfig;\r
protected TrafficAPI client;\r
protected List<Segment> segments;\r
- public TargetProcessor(Control parent, Target targetConfig, List<Segment> segments) {\r
+ protected ArchiveMetadataModel model;\r
+\r
+ public TargetProcessor(Control parent, Target targetConfig, List<Segment> segments, ArchiveMetadataModel model) {\r
this.parent = parent;\r
+ this.model = model;\r
MaestroForm maestroForm = parent as MaestroForm;\r
TrafficMetadata metadata = maestroForm.Configuration.Metadatas.Where(m => { return m is TrafficMetadata; }).FirstOrDefault() as TrafficMetadata;\r
client = new TrafficAPI(metadata.Server.Address.OriginalString, metadata.Server.UserName, metadata.Server.Password, metadata.Server.Timeout);\r
}\r
}\r
\r
+ /// <summary>\r
+ /// Looks up a localized string similar to Archive.\r
+ /// </summary>\r
+ internal static string ARCHIVE {\r
+ get {\r
+ return ResourceManager.GetString("ARCHIVE", resourceCulture);\r
+ }\r
+ }\r
+ \r
/// <summary>\r
/// Looks up a localized string similar to Global ID.\r
/// </summary>\r
<data name="ADASTUKOR" xml:space="preserve">\r
<value>Adástükör</value>\r
</data>\r
+ <data name="ARCHIVE" xml:space="preserve">\r
+ <value>Archive</value>\r
+ </data>\r
<data name="GLOBAL_ID" xml:space="preserve">\r
<value>Global ID</value>\r
</data>\r
private void InitializeComponent()\r
{\r
this.components = new System.ComponentModel.Container();\r
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();\r
this.trafficAPIBindingSource = new System.Windows.Forms.BindingSource(this.components);\r
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();\r
this.backgroundWorker2 = new System.ComponentModel.BackgroundWorker();\r
this.dataGridView1.BackgroundColor = System.Drawing.Color.White;\r
this.dataGridView1.BorderStyle = System.Windows.Forms.BorderStyle.None;\r
this.dataGridView1.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.Raised;\r
+ dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;\r
+ dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;\r
+ dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));\r
+ dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;\r
+ dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;\r
+ dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;\r
+ dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;\r
+ this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;\r
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\r
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;\r
this.dataGridView1.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;\r
this.dataGridView1.Location = new System.Drawing.Point(0, 0);\r
this.dataGridView1.MultiSelect = false;\r
this.dataGridView1.Name = "dataGridView1";\r
+ this.dataGridView1.RowHeadersVisible = false;\r
this.dataGridView1.Size = new System.Drawing.Size(263, 217);\r
this.dataGridView1.TabIndex = 0;\r
this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);\r
using System;\r
using System.Drawing;\r
using System.ComponentModel;\r
+using System.Linq;\r
+using System.Collections.Generic;\r
\r
namespace TrafficClient {\r
public delegate void OnSelectedIDChanged(string ID, int variantID);\r
new DataGridViewTextBoxColumn() {\r
AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells,\r
DataPropertyName = "MediaID",\r
- HeaderText = Resources.TRAFFIC_ID\r
+ HeaderText = Resources.TRAFFIC_ID,\r
+ \r
},\r
new DataGridViewTextBoxColumn() {\r
AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells,\r
dataGridView1.DataSource = null;\r
return;\r
}\r
- dataGridView1.DataSource = result;\r
- //dataGridView1.Sort(dataGridView1.Columns[5], ListSortDirection.Ascending);\r
+ List<MamResultWrapper> list = new List<MamResultWrapper>();\r
+ foreach (MamResultWrapper actual in result) {\r
+ list.Add(actual);\r
+ }\r
+ list.Sort((x, y) => DateTime.Compare(x.NextBroadcastDate.Value, y.NextBroadcastDate.Value));\r
+ dataGridView1.DataSource = list;\r
}\r
\r
private void textBox1_KeyDown(object sender, KeyEventArgs e) {\r
return;\r
//nincs multiselect\r
DataGridViewCell checkBoxCell = gridView.SelectedCells[0];\r
+ bool selected = checkBoxCell.Value.Equals(false);\r
clearCheckBox?.Invoke();\r
ClearSelectionSource();\r
//checkBoxCell.Value = checkBoxCell.Value.Equals(true) ? true : false;\r
MamResultWrapper res = dataGridView1.Rows[e.RowIndex].DataBoundItem as MamResultWrapper;\r
- if (checkBoxCell.Value.Equals(false))\r
- res.Selected = true;\r
- else\r
- res.Selected = false;\r
- if (checkBoxCell.Value.Equals(true)) {\r
-\r
+ res.Selected = selected;\r
+ if (selected) {\r
IDChangedEvent?.Invoke(res.MediaID, res.VariantID);\r
} else\r
IDChangedEvent?.Invoke(string.Empty, 0);\r