/// <summary> /// Merge given TagData object with current TagData object /// </summary> /// <param name="data">TagData object to merge</param> public void IntegrateValues(TagData data) { IDictionary <PictureInfo, int> picturePositions = generatePicturePositions(); // String values IDictionary <byte, String> newData = data.ToMap(); foreach (byte key in newData.Keys) { IntegrateValue(key, newData[key]); } // Pictures if (data.Pictures != null) { foreach (PictureInfo newPicInfo in data.Pictures) { // New PictureInfo picture type already exists in current TagData if (picturePositions.ContainsKey(newPicInfo)) { // New PictureInfo is a demand for deletion if (newPicInfo.MarkedForDeletion) { foreach (PictureInfo picInfo in Pictures) { if (picInfo.ToString().Equals(newPicInfo.ToString())) { picInfo.MarkedForDeletion = true; } } } else // New PictureInfo is a X-th picture of the same type { newPicInfo.Position = picturePositions[newPicInfo] + 1; Pictures.Add(newPicInfo); } } else // New PictureInfo picture type does not exist in current TagData { Pictures.Add(newPicInfo); } } } bool found; // Additional textual fields foreach (MetaFieldInfo newMetaInfo in data.AdditionalFields) { found = false; foreach (MetaFieldInfo metaInfo in AdditionalFields) { // New MetaFieldInfo tag type+field code+streamNumber+language already exists in current TagData // or new MetaFieldInfo mimics an existing field (added or edited through simplified interface) if (metaInfo.EqualsWithoutZone(newMetaInfo) || metaInfo.EqualsApproximate(newMetaInfo)) { if (newMetaInfo.MarkedForDeletion) { metaInfo.MarkedForDeletion = true; // New MetaFieldInfo is a demand for deletion } else { found = true; metaInfo.Value = newMetaInfo.Value; break; } } } if (!newMetaInfo.MarkedForDeletion && !found) // New MetaFieldInfo type+streamNumber+language does not exist in current TagData { AdditionalFields.Add(newMetaInfo); } else if (newMetaInfo.MarkedForDeletion && !found) // Cannot delete a field that has not been found { LogDelegator.GetLogDelegate()(Log.LV_WARNING, "Field code " + newMetaInfo.NativeFieldCode + " cannot be deleted because it has not been found on current TagData."); } } // Chapters, processed as a whole if (data.Chapters != null) { // Sending an existing but empty chapter list counts as a "marked for deletion" if (Chapters != null) { Chapters.Clear(); } else { Chapters = new List <ChapterInfo>(); } foreach (ChapterInfo chapter in data.Chapters) { Chapters.Add(new ChapterInfo(chapter)); } } }
private TagData toTagData() { TagData result = new TagData(); result.Title = Title; result.Artist = Artist; result.Composer = Composer; result.Comment = Comment; result.Genre = Genre; result.OriginalArtist = OriginalArtist; result.OriginalAlbum = OriginalAlbum; result.GeneralDescription = Description; result.Rating = (Popularity * 5).ToString(); result.Copyright = Copyright; result.Publisher = Publisher; if (!PublishingDate.Equals(DateTime.MinValue)) { result.PublishingDate = TrackUtils.FormatISOTimestamp(PublishingDate); } result.AlbumArtist = AlbumArtist; result.Conductor = Conductor; if (!Date.Equals(DateTime.MinValue)) { result.RecordingDate = TrackUtils.FormatISOTimestamp(Date); } result.RecordingYear = Year.ToString(); result.Album = Album; result.TrackNumber = TrackNumber.ToString(); result.TrackTotal = TrackTotal.ToString(); result.DiscNumber = DiscNumber.ToString(); result.DiscTotal = DiscTotal.ToString(); result.ChaptersTableDescription = ChaptersTableDescription.ToString(); result.Chapters = new List <ChapterInfo>(); foreach (ChapterInfo chapter in Chapters) { result.Chapters.Add(new ChapterInfo(chapter)); } if (Lyrics != null) { result.Lyrics = new LyricsInfo(Lyrics); } foreach (string s in AdditionalFields.Keys) { result.AdditionalFields.Add(new MetaFieldInfo(MetaDataIOFactory.TAG_ANY, s, AdditionalFields[s])); } // Detect and tag deleted Additional fields (=those which were in initialAdditionalFields and do not appear in AdditionalFields anymore) foreach (string s in initialAdditionalFields) { if (!AdditionalFields.ContainsKey(s)) { MetaFieldInfo metaFieldToDelete = new MetaFieldInfo(MetaDataIOFactory.TAG_ANY, s, ""); metaFieldToDelete.MarkedForDeletion = true; result.AdditionalFields.Add(metaFieldToDelete); } } result.Pictures = new List <PictureInfo>(); if (currentEmbeddedPictures != null) { foreach (PictureInfo targetPic in currentEmbeddedPictures) { targetPic.TransientFlag = 0; } } if (initialEmbeddedPictures != null && currentEmbeddedPictures != null) { foreach (PictureInfo picInfo in initialEmbeddedPictures) { // Detect and tag deleted pictures (=those which were in initialEmbeddedPictures and do not appear in embeddedPictures anymore) if (!currentEmbeddedPictures.Contains(picInfo)) { PictureInfo picToDelete = new PictureInfo(picInfo); picToDelete.MarkedForDeletion = true; result.Pictures.Add(picToDelete); } else // Only add new additions (pictures identical to initial list will be kept, and do not have to make it to the list, or else a duplicate will be created) { foreach (PictureInfo targetPic in currentEmbeddedPictures) { if (targetPic.Equals(picInfo)) { // Compare picture contents targetPic.ComputePicHash(); if (targetPic.PictureHash != picInfo.PictureHash) { // A new picture content has been defined for an existing location result.Pictures.Add(targetPic); PictureInfo picToDelete = new PictureInfo(picInfo); picToDelete.MarkedForDeletion = true; result.Pictures.Add(picToDelete); } targetPic.TransientFlag = 1; } } } } if (currentEmbeddedPictures != null) { foreach (PictureInfo targetPic in currentEmbeddedPictures) { if (0 == targetPic.TransientFlag) // Entirely new pictures without equivalent in initialEmbeddedPictures { result.Pictures.Add(targetPic); } } } } return(result); }