From 5e4e6a04a9eaba3006b2f4e9e8cbbfa1d32d15bd Mon Sep 17 00:00:00 2001 From: Martchus Date: Thu, 14 Sep 2017 21:37:25 +0200 Subject: [PATCH] Transfer notifications to media file info Commit 'Fix duplicate notifications' (0f6ac6a) caused missing notifications by omitting `addNotifications(*m_container);` before clearing parsing results. This commit restores the old behavior and will actually preserve all notifications. However, it will cause duplicated notifications again. The notification system must be reworked in v7 for a decent solution. --- mediafileinfo.cpp | 36 +++++++++++++++++++++++++++++++----- statusprovider.h | 18 ++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/mediafileinfo.cpp b/mediafileinfo.cpp index dce49d2..fa6fddc 100644 --- a/mediafileinfo.cpp +++ b/mediafileinfo.cpp @@ -1348,13 +1348,15 @@ NotificationList MediaFileInfo::gatherRelatedNotifications() const /*! * \brief Clears all parsing results and assigned/created/changed information such as - * container format, tracks, tags, ... + * detected container format, tracks, tags, ... * * This allows a rescan of the file using parsing methods like parseContainerFormat(). * Otherwise, these methods do nothing if the information to be parsed has already been * gathered. * - * \remarks Any pointers previously returned by tags(), tracks(), ... object are invalidated. + * \remarks Any pointers previously returned by tags(), tracks(), ... object should be + * considered invalidated. Notifications of those objects are transfered to + * the media file info. */ void MediaFileInfo::clearParsingResults() { @@ -1366,12 +1368,36 @@ void MediaFileInfo::clearParsingResults() m_tagsParsingStatus = ParsingStatus::NotParsedYet; m_chaptersParsingStatus = ParsingStatus::NotParsedYet; m_attachmentsParsingStatus = ParsingStatus::NotParsedYet; - m_id3v1Tag.reset(); + if(m_id3v1Tag) { + transferNotifications(*m_id3v1Tag); + m_id3v1Tag.reset(); + } + for(auto &id3v2Tag : m_id3v2Tags) { + transferNotifications(*id3v2Tag); + } m_id3v2Tags.clear(); m_actualId3v2TagOffsets.clear(); m_actualExistingId3v1Tag = false; - m_container.reset(); - m_singleTrack.reset(); + if(m_container) { + transferNotifications(*m_container); + for(size_t i = 0, count = m_container->trackCount(); i != count; ++i) { + transferNotifications(*m_container->track(i)); + } + for(size_t i = 0, count = m_container->tagCount(); i != count; ++i) { + transferNotifications(*m_container->tag(i)); + } + for(size_t i = 0, count = m_container->chapterCount(); i != count; ++i) { + transferNotifications(*m_container->chapter(i)); + } + for(size_t i = 0, count = m_container->attachmentCount(); i != count; ++i) { + transferNotifications(*m_container->attachment(i)); + } + m_container.reset(); + } + if(m_singleTrack) { + transferNotifications(*m_singleTrack); + m_singleTrack.reset(); + } } /*! diff --git a/statusprovider.h b/statusprovider.h index fc82896..043f356 100644 --- a/statusprovider.h +++ b/statusprovider.h @@ -8,8 +8,13 @@ namespace Media { +class MediaFileInfo; + class TAG_PARSER_EXPORT StatusProvider { + // FIXME: make transferNotifications() public in next minor release and get rid of the friend class again + friend class MediaFileInfo; + public: typedef std::function CallbackFunction; typedef std::vector CallbackVector; @@ -45,6 +50,7 @@ protected: private: inline void invokeCallbacks(); inline void updateWorstNotificationType(NotificationType notificationType); + inline void transferNotifications(StatusProvider &from); NotificationList m_notifications; NotificationType m_worstNotificationType; @@ -271,6 +277,18 @@ inline void StatusProvider::updateWorstNotificationType(NotificationType notific } } +/*! + * \brief Transfers all notifications from the specified status provider to the current instance. + * \remarks In constrast to the similar addNotifications() overload, this method does not copy the notifications. Instead + * the notifications are transfered. It also doesn't check whether \a from is the current instance and doesn't + * invoke callbacks. + */ +void StatusProvider::transferNotifications(StatusProvider &from) +{ + m_notifications.splice(m_notifications.end(), from.m_notifications); + m_worstNotificationType |= from.worstNotificationType(); +} + }