Fix duplicate notifications

This commit is contained in:
Martchus 2017-08-20 01:59:43 +02:00
parent a740f96875
commit 0f6ac6a7e3
2 changed files with 39 additions and 10 deletions

View File

@ -767,17 +767,26 @@ template <class ImplementationType>
void GenericFileElement<ImplementationType>::validateSubsequentElementStructure(NotificationList &gatheredNotifications, uint64 *paddingSize) void GenericFileElement<ImplementationType>::validateSubsequentElementStructure(NotificationList &gatheredNotifications, uint64 *paddingSize)
{ {
try { try {
// validate element itself by just parsing it
parse(); parse();
gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end()); gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end());
if(firstChild()) { // element is parent // validate children
if(firstChild()) {
try {
firstChild()->validateSubsequentElementStructure(gatheredNotifications, paddingSize); firstChild()->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
} catch(const Failure &) {
// - ignore critical errors in child structure to continue validating siblings
// - critical notifications about the errors should have already been added to
// gatheredNotifications
}
} else if(paddingSize && isPadding()) { // element is padding } else if(paddingSize && isPadding()) { // element is padding
*paddingSize += totalSize(); *paddingSize += totalSize();
} }
// validate siblings
if(nextSibling()) { if(nextSibling()) {
nextSibling()->validateSubsequentElementStructure(gatheredNotifications, paddingSize); nextSibling()->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
} }
} catch(Failure &) { } catch(const Failure &) {
gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end()); gatheredNotifications.insert(gatheredNotifications.end(), notifications().begin(), notifications().end());
throw; throw;
} }

View File

@ -643,7 +643,7 @@ bool MediaFileInfo::createAppropriateTags(bool treatUnknownFilesAsMp3Files, TagU
*/ */
void MediaFileInfo::applyChanges() void MediaFileInfo::applyChanges()
{ {
const string context("making file"); static const string context("making file");
addNotification(NotificationType::Information, "Changes are about to be applied.", context); addNotification(NotificationType::Information, "Changes are about to be applied.", context);
bool previousParsingSuccessful = true; bool previousParsingSuccessful = true;
switch(tagsParsingStatus()) { switch(tagsParsingStatus()) {
@ -678,9 +678,8 @@ void MediaFileInfo::applyChanges()
m_tagsParsingStatus = ParsingStatus::NotParsedYet; m_tagsParsingStatus = ParsingStatus::NotParsedYet;
try { try {
m_container->makeFile(); m_container->makeFile();
addNotifications(*m_container);
} catch(...) { } catch(...) {
addNotifications(*m_container); // since the file might be messed up, invalidate the parsing results
clearParsingResults(); clearParsingResults();
throw; throw;
} }
@ -689,6 +688,7 @@ void MediaFileInfo::applyChanges()
try { try {
makeMp3File(); makeMp3File();
} catch(...) { } catch(...) {
// since the file might be messed up, invalidate the parsing results
clearParsingResults(); clearParsingResults();
throw; throw;
} }
@ -1182,7 +1182,7 @@ vector<AbstractChapter *> MediaFileInfo::chapters() const
{ {
vector<AbstractChapter *> res; vector<AbstractChapter *> res;
if(m_container) { if(m_container) {
size_t count = m_container->chapterCount(); const size_t count = m_container->chapterCount();
res.reserve(count); res.reserve(count);
for(size_t i = 0; i != count; ++i) { for(size_t i = 0; i != count; ++i) {
res.push_back(m_container->chapter(i)); res.push_back(m_container->chapter(i));
@ -1200,9 +1200,9 @@ vector<AbstractAttachment *> MediaFileInfo::attachments() const
{ {
vector<AbstractAttachment *> res; vector<AbstractAttachment *> res;
if(m_container) { if(m_container) {
size_t count = m_container->attachmentCount(); const size_t count = m_container->attachmentCount();
res.reserve(count); res.reserve(count);
for(size_t i = 0; i < count; ++i) { for(size_t i = 0; i != count; ++i) {
res.push_back(m_container->attachment(i)); res.push_back(m_container->attachment(i));
} }
} }
@ -1284,7 +1284,27 @@ void MediaFileInfo::gatherRelatedNotifications(NotificationList &notifications)
{ {
notifications.insert(notifications.end(), this->notifications().cbegin(), this->notifications().cend()); notifications.insert(notifications.end(), this->notifications().cbegin(), this->notifications().cend());
if(m_container) { if(m_container) {
notifications.insert(notifications.end(), m_container->notifications().cbegin(), m_container->notifications().cend()); // prevent duplicates which might be present when validating element structure
switch(m_containerFormat) {
case ContainerFormat::Ebml:
case ContainerFormat::Matroska:
// those files are only validated when a full parse is forced
if(!m_forceFullParse) {
break;
}
FALLTHROUGH;
case ContainerFormat::Mp4:
case ContainerFormat::QuickTime:
// those files are always validated
for(const Notification &notification : m_container->notifications()) {
if(find(notifications.cbegin(), notifications.cend(), notification) == notifications.cend()) {
notifications.emplace_back(notification);
}
}
break;
default:
notifications.insert(notifications.end(), m_container->notifications().cbegin(), m_container->notifications().cend());;
}
} }
for(const auto *track : tracks()) { for(const auto *track : tracks()) {
notifications.insert(notifications.end(), track->notifications().cbegin(), track->notifications().cend()); notifications.insert(notifications.end(), track->notifications().cbegin(), track->notifications().cend());