From bb72b68865233242ea8f338937940159aef631e8 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 6 Jul 2009 21:49:08 +0200 Subject: [PATCH] Display an error if the user tries to save chapters that contain editions without a single chapter entry. Allow saving empty chapters to a Matroska file by removing all chapters contained in the file. Fixes for bug 422. --- ChangeLog | 8 ++++++++ src/common/kax_analyzer.cpp | 17 +++++++++++++++++ src/common/kax_analyzer.h | 1 + src/mmg/tabs/chapters.cpp | 38 +++++++++++++++++++++++++++---------- src/mmg/tabs/chapters.h | 2 +- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b87798656..c9624ed7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-07-06 Moritz Bunkus + + * mmg: bug fix: Trying to save chapters that contain editions + without a single chapter entry does no longer result in a crash + but a descriptive error message instead. Saving empty chapters to + a Matroska file will remove all chapters contained in the file + instead of not doing anything. Fixes for bug 422. + 2009-07-05 Moritz Bunkus * mkvinfo: enhancement: Implemented speed-ups of up to 50% for diff --git a/src/common/kax_analyzer.cpp b/src/common/kax_analyzer.cpp index de21e4988..50a0f9425 100644 --- a/src/common/kax_analyzer.cpp +++ b/src/common/kax_analyzer.cpp @@ -310,6 +310,23 @@ kax_analyzer_c::update_element(EbmlElement *e, return uer_success; } +kax_analyzer_c::update_element_result_e +kax_analyzer_c::remove_elements(EbmlId id) { + try { + call_and_validate({}, "remove_elements_0"); + call_and_validate(overwrite_all_instances(id), "remove_elements_1"); + call_and_validate(merge_void_elements(), "remove_elements_2"); + call_and_validate(remove_from_meta_seeks(id), "remove_elements_3"); + call_and_validate(merge_void_elements(), "remove_elements_4"); + + } catch (kax_analyzer_c::update_element_result_e result) { + debug_dump_elements_maybe("update_element_exception"); + return result; + } + + return uer_success; +} + /** \brief Sets the m_segment size to the length of the m_file */ void diff --git a/src/common/kax_analyzer.h b/src/common/kax_analyzer.h index c685fc2c8..6d90a2f2b 100644 --- a/src/common/kax_analyzer.h +++ b/src/common/kax_analyzer.h @@ -85,6 +85,7 @@ public: virtual ~kax_analyzer_c(); virtual update_element_result_e update_element(EbmlElement *e, bool write_defaults = false); + virtual update_element_result_e remove_elements(EbmlId id); virtual EbmlMaster *read_all(const EbmlCallbacks &callbacks); virtual EbmlElement *read_element(kax_analyzer_data_c *element_data); diff --git a/src/mmg/tabs/chapters.cpp b/src/mmg/tabs/chapters.cpp index ae25f859b..66a8f3f76 100644 --- a/src/mmg/tabs/chapters.cpp +++ b/src/mmg/tabs/chapters.cpp @@ -600,7 +600,7 @@ tab_chapters::on_save_chapters(wxCommandEvent &evt) { return; if (source_is_kax_file) { - display_update_element_result(analyzer->update_element(chapters)); + write_chapters_to_matroska_file(); return; } @@ -641,7 +641,7 @@ tab_chapters::on_save_chapters_to_kax_file(wxCommandEvent &evt) { return; } - display_update_element_result(analyzer->update_element(chapters)); + write_chapters_to_matroska_file(); mdlg->set_last_chapters_in_menu(file_name); } @@ -776,27 +776,43 @@ tab_chapters::verify_atom_recursively(EbmlElement *e) { bool tab_chapters::verify(bool called_interactively) { - KaxEditionEntry *eentry; uint32_t eidx, cidx; - if ((NULL == chapters) || (chapters->ListSize() == 0)) { - if (called_interactively) - wxMessageBox(Z("No chapter entries have been create yet."), Z("Chapter verification error"), wxCENTER | wxOK | wxICON_ERROR); + if (NULL == chapters){ + wxMessageBox(Z("No chapter entries have been create yet."), Z("Chapter verification error"), wxCENTER | wxOK | wxICON_ERROR); return false; } + if (0 == chapters->ListSize()) + return true; + wxTreeItemId id = tc_chapters->GetSelection(); if (id.IsOk()) copy_values(id); + for (eidx = 0; eidx < chapters->ListSize(); eidx++) { + KaxEditionEntry *eentry = static_cast((*chapters)[eidx]); + bool contains_atom = false; + + for (cidx = 0; cidx < eentry->ListSize(); cidx++) + if (dynamic_cast((*eentry)[cidx]) != NULL) { + contains_atom = true; + break; + } + + if (!contains_atom) { + wxMessageBox(Z("Each edition must contain at least one chapter."), Z("Chapter verification error"), wxCENTER | wxOK | wxICON_ERROR); + return false; + } + } + fix_mandatory_chapter_elements(chapters); for (eidx = 0; eidx < chapters->ListSize(); eidx++) { - eentry = static_cast((*chapters)[eidx]); - for (cidx = 0; cidx < eentry->ListSize(); cidx++) { + KaxEditionEntry *eentry = static_cast((*chapters)[eidx]); + for (cidx = 0; cidx < eentry->ListSize(); cidx++) if ((dynamic_cast((*eentry)[cidx]) != NULL) && !verify_atom_recursively((*eentry)[cidx])) return false; - } } if (!chapters->CheckMandatory()) @@ -1859,7 +1875,9 @@ tab_chapters::is_empty() { } void -tab_chapters::display_update_element_result(kax_analyzer_c::update_element_result_e result) { +tab_chapters::write_chapters_to_matroska_file() { + kax_analyzer_c::update_element_result_e result = (0 == chapters->ListSize() ? analyzer->remove_elements(KaxChapters::ClassInfos.GlobalId) : analyzer->update_element(chapters)); + switch (result) { case kax_analyzer_c::uer_success: mdlg->set_status_bar(Z("Chapters written.")); diff --git a/src/mmg/tabs/chapters.h b/src/mmg/tabs/chapters.h index ff4bf40e4..0af2b2985 100644 --- a/src/mmg/tabs/chapters.h +++ b/src/mmg/tabs/chapters.h @@ -119,7 +119,7 @@ public: bool is_empty(); protected: - void display_update_element_result(kax_analyzer_c::update_element_result_e result); + void write_chapters_to_matroska_file(); }; #endif // __TAB_CHAPTERS_H