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.
This commit is contained in:
Martchus 2017-09-14 21:37:25 +02:00
parent 098c54e016
commit 5e4e6a04a9
2 changed files with 49 additions and 5 deletions

View File

@ -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();
}
}
/*!

View File

@ -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<void (StatusProvider &sender)> CallbackFunction;
typedef std::vector<CallbackFunction> 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();
}
}