diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index 26e1c5a05..172956a32 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -104,16 +104,6 @@ void AssFile::Load(const wxString &_filename,wxString charset,bool addToRecent) catch (agi::UserCancelException const&) { return; } - catch (const char *except) { - wxMessageBox(except,"Error loading file",wxICON_ERROR | wxOK); - return; - } - - catch (wxString &except) { - wxMessageBox(except,"Error loading file",wxICON_ERROR | wxOK); - return; - } - // Real exception catch (agi::Exception &e) { wxMessageBox(lagi_wxString(e.GetChainedMessage()), "Error loading file", wxICON_ERROR|wxOK); diff --git a/aegisub/src/auto4_base.cpp b/aegisub/src/auto4_base.cpp index da1174b56..993c395ab 100644 --- a/aegisub/src/auto4_base.cpp +++ b/aegisub/src/auto4_base.cpp @@ -360,6 +360,7 @@ namespace Automation4 { /// FeatureSubtitleFormat::FeatureSubtitleFormat(const wxString &_name, const wxString &_extension) : Feature(SCRIPTFEATURE_SUBFORMAT, _name) + , SubtitleFormat(_name) , extension(_extension) { // nothing to do diff --git a/aegisub/src/subtitle_format.cpp b/aegisub/src/subtitle_format.cpp index 2e644a145..311fbdce0 100644 --- a/aegisub/src/subtitle_format.cpp +++ b/aegisub/src/subtitle_format.cpp @@ -41,6 +41,7 @@ #include // Keep this last so wxUSE_CHOICEDLG is set. #endif +#include "ass_dialogue.h" #include "ass_file.h" #include "subtitle_format.h" #include "subtitle_format_ass.h" @@ -52,47 +53,42 @@ #include "subtitle_format_transtation.h" #include "subtitle_format_ttxt.h" #include "subtitle_format_txt.h" +#include "utils.h" #include "video_context.h" -/// @brief Constructor -/// -SubtitleFormat::SubtitleFormat() { - Line = NULL; - Register(); - isCopy = false; +using namespace std::tr1::placeholders; + +SubtitleFormat::SubtitleFormat(wxString const& name) +: name(name) +, isCopy(0) +, Line(0) +{ + formats.push_back(this); } -/// @brief Destructor -/// -SubtitleFormat::~SubtitleFormat () { - Remove(); +SubtitleFormat::~SubtitleFormat() { + formats.remove(this); } -/// DOCME -std::list SubtitleFormat::formats; - -/// DOCME -bool SubtitleFormat::loaded = false; - -/// @brief Set target -/// @param file -/// void SubtitleFormat::SetTarget(AssFile *file) { ClearCopy(); - if (!file) Line = NULL; - else Line = &file->Line; + Line = file ? &file->Line : 0; assFile = file; } -/// @brief Create copy -/// +bool SubtitleFormat::CanReadFile(wxString const& filename) const { + return GetReadWildcards().Index(filename.AfterLast('.'), false) != wxNOT_FOUND; +} + +bool SubtitleFormat::CanWriteFile(wxString const& filename) const { + return GetWriteWildcards().Index(filename.AfterLast('.'), false) != wxNOT_FOUND; +} + void SubtitleFormat::CreateCopy() { SetTarget(new AssFile(*assFile)); isCopy = true; } -/// @brief Clear copy -/// void SubtitleFormat::ClearCopy() { if (isCopy) { delete assFile; @@ -101,184 +97,19 @@ void SubtitleFormat::ClearCopy() { } } -/// @brief Clear subtitles -/// void SubtitleFormat::Clear() { assFile->Clear(); } -/// @brief Load default -/// @param defline -/// void SubtitleFormat::LoadDefault(bool defline) { assFile->LoadDefault(defline); } -/// @brief Add line -/// @param data -/// @param group -/// @param version -/// @param outgroup -void SubtitleFormat::AddLine(wxString data,wxString group,int &version,wxString *outgroup) { - assFile->AddLine(data,group,version,outgroup); -} - -/// @brief Add formats -/// -void SubtitleFormat::LoadFormats () { - if (!loaded) { - new ASSSubtitleFormat(); - new SRTSubtitleFormat(); - new TXTSubtitleFormat(); - new TTXTSubtitleFormat(); - new MicroDVDSubtitleFormat(); - new MKVSubtitleFormat(); - new EncoreSubtitleFormat(); - new TranStationSubtitleFormat(); -#ifdef _DEBUG - new DVDSubtitleFormat(); -#endif - } - loaded = true; -} - -/// @brief Destroy formats -/// -void SubtitleFormat::DestroyFormats () { - std::list::iterator cur; - for (cur=formats.begin();cur!=formats.end();cur = formats.begin()) { - delete *cur; - } - formats.clear(); -} - -/// @brief Get an appropriate reader -/// @param filename -/// @return -/// -SubtitleFormat *SubtitleFormat::GetReader(wxString filename) { - LoadFormats(); - std::list::iterator cur; - SubtitleFormat *reader; - for (cur=formats.begin();cur!=formats.end();cur++) { - reader = *cur; - if (reader->CanReadFile(filename)) return reader; - } - return NULL; -} - -/// @brief Get an appropriate writer -/// @param filename -/// @return -/// -SubtitleFormat *SubtitleFormat::GetWriter(wxString filename) { - LoadFormats(); - std::list::iterator cur; - SubtitleFormat *writer; - for (cur=formats.begin();cur!=formats.end();cur++) { - writer = *cur; - if (writer->CanWriteFile(filename)) return writer; - } - return NULL; -} - -/// @brief Register -/// @return -/// -void SubtitleFormat::Register() { - std::list::iterator cur; - for (cur=formats.begin();cur!=formats.end();cur++) { - if (*cur == this) return; - } - formats.push_back(this); -} - -/// @brief Remove -/// @return -/// -void SubtitleFormat::Remove() { - std::list::iterator cur; - for (cur=formats.begin();cur!=formats.end();cur++) { - if (*cur == this) { - formats.erase(cur); - return; - } - } -} - -/// @brief Get read wildcards -/// @return -/// -wxArrayString SubtitleFormat::GetReadWildcards() { - return wxArrayString(); -} - -/// @brief Get write wildcards -/// @return -/// -wxArrayString SubtitleFormat::GetWriteWildcards() { - return wxArrayString(); -} - -/// @brief Get wildcard list -/// @param mode -/// @return -/// -wxString SubtitleFormat::GetWildcards(int mode) { - // Ensure it's loaded - LoadFormats(); - - // Variables - wxArrayString all; - wxArrayString cur; - wxString wild; - wxString final; - wxString temp1; - wxString temp2; - - // For each format - std::list::iterator curIter; - SubtitleFormat *format; - for (curIter=formats.begin();curIter!=formats.end();curIter++) { - // Get list - format = *curIter; - if (mode == 0) cur = format->GetReadWildcards(); - else if (mode == 1) cur = format->GetWriteWildcards(); - temp1.Clear(); - temp2.Clear(); - - // Has wildcards - if (cur.Count()) { - // Process entries - for (unsigned int i=0;iGetName() + " (" + temp1.Left(temp1.Length()-1) + ")|" + temp2.Left(temp2.Length()-1) + "|"; - } - } - - // Add "all formats" list - temp1.Clear(); - temp2.Clear(); - for (unsigned int i=0;iAddLine(data, group, version, outgroup); } /// @brief Ask the user to enter the FPS -/// @param showSMPTE -/// @return -/// SubtitleFormat::FPSRational SubtitleFormat::AskForFPS(bool showSMPTE) { wxArrayString choices; FPSRational fps_rat; @@ -290,8 +121,8 @@ SubtitleFormat::FPSRational SubtitleFormat::AskForFPS(bool showSMPTE) { if (vidLoaded) { wxString vidFPS; if (context->FPS().IsVFR()) vidFPS = "VFR"; - else vidFPS = wxString::Format("%.3f",context->FPS().FPS()); - choices.Add(wxString::Format("From video (%s)",vidFPS)); + else vidFPS = wxString::Format("%.3f", context->FPS().FPS()); + choices.Add(wxString::Format("From video (%s)", vidFPS)); } // Standard FPS values @@ -310,7 +141,7 @@ SubtitleFormat::FPSRational SubtitleFormat::AskForFPS(bool showSMPTE) { choices.Add(_("120.000 FPS")); // Ask - int choice = wxGetSingleChoiceIndex(_("Please choose the appropriate FPS for the subtitles:"),_("FPS"),choices); + int choice = wxGetSingleChoiceIndex(_("Please choose the appropriate FPS for the subtitles:"), _("FPS"), choices); if (choice == -1) { fps_rat.num = 0; fps_rat.den = 0; @@ -364,191 +195,143 @@ SubtitleFormat::FPSRational SubtitleFormat::AskForFPS(bool showSMPTE) { return fps_rat; } -/// @brief Sort lines -/// void SubtitleFormat::SortLines() { AssFile::Sort(*Line); } -/// @brief Convert tags -/// @param format -/// @param lineEnd -/// -void SubtitleFormat::ConvertTags(int format,const wxString &lineEnd,bool mergeLineBreaks) { - using std::list; - list::iterator next; - for (list::iterator cur=Line->begin();cur!=Line->end();cur++) { - AssDialogue *current = dynamic_cast(*cur); - if (current) { +void SubtitleFormat::ConvertTags(int format, const wxString &lineEnd, bool mergeLineBreaks) { + for (std::list::iterator cur = Line->begin(); cur != Line->end(); ++cur) { + if (AssDialogue *current = dynamic_cast(*cur)) { // Strip tags if (format == 1) current->StripTags(); else if (format == 2) current->ConvertTagsToSRT(); // Replace line breaks - current->Text.Replace("\\h"," ",true); - current->Text.Replace("\\n",lineEnd,true); - current->Text.Replace("\\N",lineEnd,true); + current->Text.Replace("\\h", " "); + current->Text.Replace("\\n", lineEnd); + current->Text.Replace("\\N", lineEnd); if (mergeLineBreaks) { - while (current->Text.Replace(lineEnd+lineEnd,lineEnd,true)) {}; + while (current->Text.Replace(lineEnd+lineEnd, lineEnd)); } } } } -/// @brief Remove all comment lines -/// void SubtitleFormat::StripComments() { - using std::list; - list::iterator next; - - for (list::iterator cur = Line->begin(); cur != Line->end(); cur = next) { - next = cur; - next++; - - AssDialogue *dlg = dynamic_cast(*cur); - if (dlg && (dlg->Comment || dlg->Text.IsEmpty())) { - delete *cur; - Line->erase(cur); + for (std::list::iterator it = Line->begin(); it != Line->end(); ) { + AssDialogue *diag = dynamic_cast(*it); + if (!diag || (!diag->Comment && diag->Text.size())) + ++it; + else { + delete *it; + Line->erase(it++); } } } -/// @brief Remove all non-dialogue lines -/// void SubtitleFormat::StripNonDialogue() { - using std::list; - list::iterator next; - - for (list::iterator cur = Line->begin(); cur != Line->end(); cur = next) { - next = cur; - next++; - - if (!dynamic_cast(*cur)) { - delete *cur; - Line->erase(cur); + for (std::list::iterator it = Line->begin(); it != Line->end(); ) { + if (dynamic_cast(*it)) + ++it; + else { + delete *it; + Line->erase(it++); } } } -/// @brief Helper function for RecombineOverlaps() -/// @param list -/// @param next -/// @param newdlg -/// -static void InsertLineSortedIntoList(std::list &list, std::list::iterator next, AssDialogue *newdlg) { - std::list::iterator insertpos = next; - bool inserted = false; - while (insertpos != list.end()) { - AssDialogue *candidate = dynamic_cast(*insertpos); - if (candidate && candidate->Start >= newdlg->Start) { - list.insert(insertpos, newdlg); - inserted = true; - break; - } - insertpos++; - } - if (!inserted) { - list.push_back(newdlg); - } +static bool dialog_start_lt(AssEntry *pos, AssDialogue *to_insert) { + AssDialogue *diag = dynamic_cast(pos); + return diag && diag->Start > to_insert->Start; } /// @brief Split and merge lines so there are no overlapping lines /// /// Algorithm described at http://devel.aegisub.org/wiki/Technical/SplitMerge void SubtitleFormat::RecombineOverlaps() { - using std::list; - list::iterator next; - - for (list::iterator cur = Line->begin(); cur != Line->end(); cur = next) { - next = cur; - next++; - - if (next == Line->end()) break; - + std::list::iterator cur, next = Line->begin(); + cur = next++; + + for (; next != Line->end(); cur = next++) { AssDialogue *prevdlg = dynamic_cast(*cur); AssDialogue *curdlg = dynamic_cast(*next); - - if (curdlg && prevdlg && prevdlg->End > curdlg->Start) { - // Use names like in the algorithm description and prepare for erasing - // old dialogues from the list - list::iterator prev = cur; - cur = next; - next++; - - // std::list::insert() inserts items before the given iterator, so - // we need 'next' for inserting. 'prev' and 'cur' can safely be erased - // from the list now. - Line->erase(prev); - Line->erase(cur); - - //Is there an A part before the overlap? - if (curdlg->Start > prevdlg->Start) { - // Produce new entry with correct values - AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); - newdlg->Start = prevdlg->Start; - newdlg->End = curdlg->Start; - newdlg->Text = prevdlg->Text; - - InsertLineSortedIntoList(*Line, next, newdlg); - } - - // Overlapping A+B part - { - AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); - newdlg->Start = curdlg->Start; - newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End; - // Put an ASS format hard linewrap between lines - newdlg->Text = curdlg->Text + "\\N" + prevdlg->Text; - - InsertLineSortedIntoList(*Line, next, newdlg); - } - - // Is there an A part after the overlap? - if (prevdlg->End > curdlg->End) { - // Produce new entry with correct values - AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); - newdlg->Start = curdlg->End; - newdlg->End = prevdlg->End; - newdlg->Text = prevdlg->Text; - - InsertLineSortedIntoList(*Line, next, newdlg); - } - - // Is there a B part after the overlap? - if (curdlg->End > prevdlg->End) { - // Produce new entry with correct values - AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); - newdlg->Start = prevdlg->End; - newdlg->End = curdlg->End; - newdlg->Text = curdlg->Text; - - InsertLineSortedIntoList(*Line, next, newdlg); - } - - next--; + + if (!curdlg || !prevdlg) continue; + if (prevdlg->End <= curdlg->Start) continue; + + // Use names like in the algorithm description and prepare for erasing + // old dialogues from the list + std::list::iterator prev = cur; + cur = next; + next++; + + // std::list::insert() inserts items before the given iterator, so + // we need 'next' for inserting. 'prev' and 'cur' can safely be erased + // from the list now. + Line->erase(prev); + Line->erase(cur); + + //Is there an A part before the overlap? + if (curdlg->Start > prevdlg->Start) { + // Produce new entry with correct values + AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); + newdlg->Start = prevdlg->Start; + newdlg->End = curdlg->Start; + newdlg->Text = prevdlg->Text; + + Line->insert(find_if(next, Line->end(), bind(dialog_start_lt, _1, newdlg)), newdlg); } + + // Overlapping A+B part + { + AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); + newdlg->Start = curdlg->Start; + newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End; + // Put an ASS format hard linewrap between lines + newdlg->Text = curdlg->Text + "\\N" + prevdlg->Text; + + Line->insert(find_if(next, Line->end(), bind(dialog_start_lt, _1, newdlg)), newdlg); + } + + // Is there an A part after the overlap? + if (prevdlg->End > curdlg->End) { + // Produce new entry with correct values + AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); + newdlg->Start = curdlg->End; + newdlg->End = prevdlg->End; + newdlg->Text = prevdlg->Text; + + Line->insert(find_if(next, Line->end(), bind(dialog_start_lt, _1, newdlg)), newdlg); + } + + // Is there a B part after the overlap? + if (curdlg->End > prevdlg->End) { + // Produce new entry with correct values + AssDialogue *newdlg = dynamic_cast(prevdlg->Clone()); + newdlg->Start = prevdlg->End; + newdlg->End = curdlg->End; + newdlg->Text = curdlg->Text; + + Line->insert(find_if(next, Line->end(), bind(dialog_start_lt, _1, newdlg)), newdlg); + } + + next--; } } /// @brief Merge identical lines that follow each other -/// void SubtitleFormat::MergeIdentical() { - using std::list; - list::iterator next; + std::list::iterator cur, next = Line->begin(); + cur = next++; - for (list::iterator cur = Line->begin(); cur != Line->end(); cur = next) { - next = cur; - next++; - - if (next == Line->end()) break; - + for (; next != Line->end(); cur = next++) { AssDialogue *curdlg = dynamic_cast(*cur); AssDialogue *nextdlg = dynamic_cast(*next); if (curdlg && nextdlg && curdlg->End == nextdlg->Start && curdlg->Text == nextdlg->Text) { // Merge timing - nextdlg->Start = (nextdlg->Start < curdlg->Start ? nextdlg->Start : curdlg->Start); - nextdlg->End = (nextdlg->End > curdlg->End ? nextdlg->End : curdlg->End); + nextdlg->Start = std::min(nextdlg->Start, curdlg->Start); + nextdlg->End = std::max(nextdlg->End, curdlg->End); // Remove duplicate line delete *cur; @@ -556,3 +339,66 @@ void SubtitleFormat::MergeIdentical() { } } } + +std::list SubtitleFormat::formats; + +void SubtitleFormat::LoadFormats() { + if (formats.empty()) { + new ASSSubtitleFormat(); + new EncoreSubtitleFormat(); + new MKVSubtitleFormat(); + new MicroDVDSubtitleFormat(); + new SRTSubtitleFormat(); + new TTXTSubtitleFormat(); + new TXTSubtitleFormat(); + new TranStationSubtitleFormat(); +#ifdef _DEBUG + new DVDSubtitleFormat(); +#endif + } +} + +void SubtitleFormat::DestroyFormats() { + for (std::list::iterator it = formats.begin(); it != formats.end(); ) + delete *it++; +} + +template +SubtitleFormat *find_or_null(Cont &container, Pred pred) { + typename Cont::iterator it = find_if(container.begin(), container.end(), pred); + if (it == container.end()) + return 0; + return *it; +} + +SubtitleFormat *SubtitleFormat::GetReader(wxString const& filename) { + LoadFormats(); + return find_or_null(formats, bind(&SubtitleFormat::CanReadFile, _1, filename)); +} + +SubtitleFormat *SubtitleFormat::GetWriter(wxString const& filename) { + LoadFormats(); + return find_or_null(formats, bind(&SubtitleFormat::CanWriteFile, _1, filename)); +} + +wxString SubtitleFormat::GetWildcards(int mode) { + LoadFormats(); + + wxArrayString all; + wxString final; + + std::list::iterator curIter; + for (curIter=formats.begin();curIter!=formats.end();curIter++) { + SubtitleFormat *format = *curIter; + wxArrayString cur = mode == 0 ? format->GetReadWildcards() : format->GetWriteWildcards(); + if (cur.empty()) continue; + + for_each(cur.begin(), cur.end(), bind(&wxString::Prepend, _1, "*.")); + copy(cur.begin(), cur.end(), std::back_inserter(all)); + final += "|" + format->GetName() + " (" + wxJoin(cur, ',') + ")|" + wxJoin(cur, ';'); + } + + final.Prepend(_("All Supported Formats") + " (" + wxJoin(all, ',') + ")|" + wxJoin(all, ';')); + + return final; +} diff --git a/aegisub/src/subtitle_format.h b/aegisub/src/subtitle_format.h index 936fb2f50..de9641d78 100644 --- a/aegisub/src/subtitle_format.h +++ b/aegisub/src/subtitle_format.h @@ -54,96 +54,113 @@ class AssEntry; /// /// DOCME class SubtitleFormat { - /// DOCME + wxString name; bool isCopy; - - /// DOCME AssFile *assFile; - void Register(); - void Remove(); + /// Get this format's wildcards for a load dialog + virtual wxArrayString GetReadWildcards() const { return wxArrayString(); } + /// Get this format's wildcards for a save dialog + virtual wxArrayString GetWriteWildcards() const { return wxArrayString(); } - /// DOCME + /// List of loaded subtitle formats static std::list formats; - /// DOCME - static bool loaded; - protected: - /// DOCME struct FPSRational { - - /// DOCME int num; - - /// DOCME int den; - - /// DOCME bool smpte_dropframe; }; - /// DOCME std::list *Line; + /// Copy the input subtitles file; must be called before making any changes void CreateCopy(); + /// Delete the subtitle file if we own it; should be called after processing + /// if CreateCopy was used void ClearCopy(); + /// Sort the lines by start time void SortLines(); - void ConvertTags(int format,const wxString &lineEnd,bool mergeLineBreaks=true); - //void Merge(bool identical,bool overlaps,bool stripComments,bool stripNonDialogue); + /// Strip tags or convert them to SRT + /// @param format 1: strip tags 2: SRT + /// @param lineEnd Newline character(s) + /// @param mergeLineBreaks Should multiple consecutive line breaks be merged into one? + void ConvertTags(int format, const wxString &lineEnd, bool mergeLineBreaks=true); + /// Remove All commented and empty lines void StripComments(); + /// Remove everything but the dialogue lines void StripNonDialogue(); + /// @brief Split and merge lines so there are no overlapping lines + /// + /// Algorithm described at http://devel.aegisub.org/wiki/Technical/SplitMerge void RecombineOverlaps(); + /// Merge sequential identical lines void MergeIdentical(); + /// Clear the subtitle file void Clear(); + /// Load the default file + /// @param defline Add a blank line? void LoadDefault(bool defline=true); - /// @brief DOCME - /// @return - /// AssFile *GetAssFile() { return assFile; } + /// Add a line to the output file + /// @param data Line data + /// @param group File section void AddLine(wxString data,wxString group,int &version,wxString *outgroup=NULL); + /// Prompt the user for a framerate to use + /// @param showSMPTE Include SMPTE as an option? FPSRational AskForFPS(bool showSMPTE=false); - virtual wxString GetName()=0; - virtual wxArrayString GetReadWildcards(); - virtual wxArrayString GetWriteWildcards(); - public: - SubtitleFormat(); + /// Constructor + /// @param Subtitle format name + /// @note Automatically registers the format + SubtitleFormat(wxString const& name); + /// Destructor + /// @note Automatically unregisters the format virtual ~SubtitleFormat(); + + /// Set the target file to write void SetTarget(AssFile *file); + /// Get this format's name + wxString GetName() const { return name; } + + /// @brief Check if the given file can be read by this format + /// + /// Default implemention simply checks if the file's extension is in the + /// format's wildcard list + virtual bool CanReadFile(wxString const& filename) const; + + /// @brief Check if the given file can be written by this format + /// + /// Default implemention simply checks if the file's extension is in the + /// format's wildcard list + virtual bool CanWriteFile(wxString const& filename) const; + + /// Load a subtitle file + /// @param filename File to load + /// @param forceEncoding Encoding to use or empty string for default + virtual void ReadFile(wxString const& filename, wxString const& forceEncoding="") { } + + /// Save a subtitle file + /// @param filename File to write to + /// @param forceEncoding Encoding to use or empty string for default + virtual void WriteFile(wxString const& filename, wxString const& encoding="") { } + + /// Get the wildcards for a save or load dialog + /// @param mode 0: load 1: save static wxString GetWildcards(int mode); - /// @brief DOCME - /// @param filename - /// @return - /// - virtual bool CanReadFile(wxString filename) { return false; }; - - /// @brief DOCME - /// @param filename - /// @return - /// - virtual bool CanWriteFile(wxString filename) { return false; }; - - /// @brief DOCME - /// @param filename - /// @param forceEncoding - /// - virtual void ReadFile(wxString filename,wxString forceEncoding="") { }; - - /// @brief DOCME - /// @param filename - /// @param encoding - /// - virtual void WriteFile(wxString filename,wxString encoding="") { }; - - static SubtitleFormat *GetReader(wxString filename); - static SubtitleFormat *GetWriter(wxString filename); + /// Get a subtitle format that can read the given file or NULL if none can + static SubtitleFormat *GetReader(wxString const& filename); + /// Get a subtitle format that can write the given file or NULL if none can + static SubtitleFormat *GetWriter(wxString const& filename); + /// Initialize subtitle formats static void LoadFormats(); + /// Deinitialize subtitle formats static void DestroyFormats(); }; diff --git a/aegisub/src/subtitle_format_ass.cpp b/aegisub/src/subtitle_format_ass.cpp index 932e564d5..455c6d282 100644 --- a/aegisub/src/subtitle_format_ass.cpp +++ b/aegisub/src/subtitle_format_ass.cpp @@ -34,148 +34,92 @@ /// @ingroup subtitle_io /// - -/////////// -// Headers #include "config.h" -#include "ass_dialogue.h" #include "subtitle_format_ass.h" + +#include "ass_dialogue.h" +#include "compat.h" #include "text_file_reader.h" #include "text_file_writer.h" +DEFINE_SIMPLE_EXCEPTION(AssParseError, SubtitleFormatParseError, "subtitle_io/parse/ass") -/// @brief Can read? -/// @param filename -/// @return -/// -bool ASSSubtitleFormat::CanReadFile(wxString filename) { - return (filename.Right(4).Lower() == ".ass" || filename.Right(4).Lower() == ".ssa"); +ASSSubtitleFormat::ASSSubtitleFormat() +: SubtitleFormat("Advanced Substation Alpha") +{ } - - -/// @brief Get name -/// @return -/// -wxString ASSSubtitleFormat::GetName() { - return "Advanced Substation Alpha"; -} - - - -/// @brief Get read wildcards -/// @return -/// -wxArrayString ASSSubtitleFormat::GetReadWildcards() { +wxArrayString ASSSubtitleFormat::GetReadWildcards() const { wxArrayString formats; formats.Add("ass"); formats.Add("ssa"); return formats; } - - -/// @brief Get write wildcards -/// @return -/// -wxArrayString ASSSubtitleFormat::GetWriteWildcards() { +wxArrayString ASSSubtitleFormat::GetWriteWildcards() const { wxArrayString formats; formats.Add("ass"); formats.Add("ssa"); return formats; } - - -/// @brief Read file -/// @param filename -/// @param encoding -/// -void ASSSubtitleFormat::ReadFile(wxString filename,wxString encoding) { +void ASSSubtitleFormat::ReadFile(wxString const& filename, wxString const& encoding) { using namespace std; - // Reader - TextFileReader file(filename,encoding); - int version = 1; - if (filename.Right(4).Lower() == ".ssa") version = 0; + TextFileReader file(filename, encoding); + int version = filename.Right(4).Lower() != ".ssa"; - // Parse file wxString curgroup; - wxString wxbuffer; while (file.HasMoreLines()) { - // Reads line - wxbuffer = file.ReadLineFromFile(); + wxString line = file.ReadLineFromFile(); // Make sure that the first non-blank non-comment non-group-header line // is really [Script Info] - if (curgroup.IsEmpty() && !wxbuffer.IsEmpty() && wxbuffer[0] != ';' && wxbuffer[0] != '[') { + if (curgroup.empty() && !line.empty() && line[0] != ';' && line[0] != '[') { curgroup = "[Script Info]"; - AddLine(curgroup,curgroup,version,&curgroup); + AddLine(curgroup, curgroup, version, &curgroup); } // Convert v4 styles to v4+ styles - if (!wxbuffer.IsEmpty() && wxbuffer[0] == '[') { + if (!line.empty() && line[0] == '[') { // Ugly hacks to allow intermixed v4 and v4+ style sections - wxString low = wxbuffer.Lower(); + wxString low = line.Lower(); if (low == "[v4 styles]") { - wxbuffer = "[V4+ Styles]"; - curgroup = wxbuffer; + line = "[V4+ Styles]"; + curgroup = line; version = 0; } else if (low == "[v4+ styles]") { - wxbuffer = "[V4+ Styles]"; - curgroup = wxbuffer; + line = "[V4+ Styles]"; + curgroup = line; version = 1; } else if (low == "[v4++ styles]") { - wxbuffer = "[V4+ Styles]"; - curgroup = wxbuffer; + line = "[V4+ Styles]"; + curgroup = line; version = 2; } // Not-so-special case for other groups, just set it else { - curgroup = wxbuffer; + curgroup = line; } } - // Add line try { - AddLine(wxbuffer,curgroup,version,&curgroup); + AddLine(line, curgroup, version, &curgroup); } catch (const char *err) { Clear(); - throw wxString("Error processing line: ") + wxbuffer + ": " + wxString(err); - } - catch (...) { - Clear(); - throw wxString("Error processing line: ") + wxbuffer; + throw AssParseError("Error processing line: " + STD_STR(line) + ": " + err, 0); } } } - - -/// @brief Can write to file? -/// @param filename -/// @return -/// -bool ASSSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Right(4).Lower() == ".ass" || filename.Right(4).Lower() == ".ssa"); -} - - - -/// @brief Write file -/// @param _filename -/// @param encoding -/// -void ASSSubtitleFormat::WriteFile(wxString filename,wxString encoding) { - // Open file - TextFileWriter file(filename,encoding); +void ASSSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { + TextFileWriter file(filename, encoding); bool ssa = filename.Right(4).Lower() == ".ssa"; - // Write lines std::list::iterator last = Line->end(); --last; wxString group = Line->front()->group; for (std::list::iterator cur=Line->begin(); cur!=Line->end(); ++cur) { @@ -189,9 +133,7 @@ void ASSSubtitleFormat::WriteFile(wxString filename,wxString encoding) { bool lineBreak = cur != last; // Write line - if (ssa) file.WriteLineToFile((*cur)->GetSSAText(),lineBreak); - else file.WriteLineToFile((*cur)->GetEntryData(),lineBreak); + if (ssa) file.WriteLineToFile((*cur)->GetSSAText(), lineBreak); + else file.WriteLineToFile((*cur)->GetEntryData(), lineBreak); } } - - diff --git a/aegisub/src/subtitle_format_ass.h b/aegisub/src/subtitle_format_ass.h index 93eb6ac18..53317ebca 100644 --- a/aegisub/src/subtitle_format_ass.h +++ b/aegisub/src/subtitle_format_ass.h @@ -34,20 +34,8 @@ /// @ingroup subtitle_io /// - - - -/////////// -// Headers #include "subtitle_format.h" - -////////////// -// Prototypes -class AssDialogue; - - - /// DOCME /// @class ASSSubtitleFormat /// @brief DOCME @@ -55,15 +43,11 @@ class AssDialogue; /// DOCME class ASSSubtitleFormat : public SubtitleFormat { public: - wxString GetName(); - wxArrayString GetReadWildcards(); - wxArrayString GetWriteWildcards(); + ASSSubtitleFormat(); - bool CanReadFile(wxString filename); - void ReadFile(wxString filename,wxString forceEncoding); + wxArrayString GetReadWildcards() const; + wxArrayString GetWriteWildcards() const; - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + void ReadFile(wxString const& filename, wxString const& forceEncoding); + void WriteFile(wxString const& filename, wxString const& encoding); }; - - diff --git a/aegisub/src/subtitle_format_dvd.cpp b/aegisub/src/subtitle_format_dvd.cpp index f28723c02..8872b4fa7 100644 --- a/aegisub/src/subtitle_format_dvd.cpp +++ b/aegisub/src/subtitle_format_dvd.cpp @@ -34,19 +34,16 @@ /// @ingroup subtitle_io vobsub /// - -/////////// -// Headers #include "config.h" +#include "subtitle_format_dvd.h" + #include "ass_dialogue.h" #include "ass_file.h" -#include "subtitle_format_dvd.h" #include "include/aegisub/subtitles_provider.h" #include "video_provider_dummy.h" -/// DOCME #undef _OPENMP #ifdef _OPENMP #include @@ -58,41 +55,17 @@ // //#pragma comment(lib, "tessdll.lib") - - -/// @brief Format name -/// @return -/// -wxString DVDSubtitleFormat::GetName() { - return "DVD Subpictures"; +DVDSubtitleFormat::DVDSubtitleFormat() +: SubtitleFormat("DVD Subpictures") +{ } - - -/// @brief Extensions -/// @return -/// -wxArrayString DVDSubtitleFormat::GetWriteWildcards() { +wxArrayString DVDSubtitleFormat::GetWriteWildcards() const { wxArrayString results; results.Add("sup"); return results; } - - -/// @brief Can write -/// @param filename -/// @return -/// -bool DVDSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Lower().EndsWith(".sup")); -} - - - -/// @brief Get subpicture list -/// @param pics -/// void DVDSubtitleFormat::GetSubPictureList(std::vector &pics) { // Create video frame int w = 720; @@ -361,7 +334,7 @@ void DVDSubtitleFormat::GetSubPictureList(std::vector &pics) { /// @param filename /// @param encoding /// -void DVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) { +void DVDSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { // Prepare subtitles CreateCopy(); SortLines(); diff --git a/aegisub/src/subtitle_format_dvd.h b/aegisub/src/subtitle_format_dvd.h index a05f7aaef..206a709f1 100644 --- a/aegisub/src/subtitle_format_dvd.h +++ b/aegisub/src/subtitle_format_dvd.h @@ -34,18 +34,12 @@ /// @ingroup subtitle_io vobsub /// - - - -/////////// -// Headers #ifndef AGI_PRE #include #endif #include "subtitle_format.h" - /// DOCME struct SubPicture { @@ -55,17 +49,17 @@ struct SubPicture { /// DOCME /// DOCME - int x,y; + int x, y; /// DOCME /// DOCME - int w,h; + int w, h; /// DOCME /// DOCME - int start,end; + int start, end; }; @@ -81,12 +75,7 @@ struct RLEGroup { /// DOCME bool eol; - /// @brief DOCME - /// @param _col - /// @param _len - /// @param _eol - /// - RLEGroup(int _col,int _len,bool _eol) { col = _col; len = _len; eol = _eol; } + RLEGroup(int col, int len, bool eol) : col(col), len(len), eol(eol) { } }; @@ -97,14 +86,10 @@ struct RLEGroup { /// /// DOCME class DVDSubtitleFormat : public SubtitleFormat { -private: void GetSubPictureList(std::vector &pics); public: - wxString GetName(); - wxArrayString GetWriteWildcards(); - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + DVDSubtitleFormat(); + wxArrayString GetWriteWildcards() const; + void WriteFile(wxString const& filename, wxString const& encoding); }; - - diff --git a/aegisub/src/subtitle_format_encore.cpp b/aegisub/src/subtitle_format_encore.cpp index dd7f92fdb..9c118c7ed 100644 --- a/aegisub/src/subtitle_format_encore.cpp +++ b/aegisub/src/subtitle_format_encore.cpp @@ -34,57 +34,29 @@ /// @ingroup subtitle_io /// - -/////////// -// Headers #include "config.h" -#include "ass_dialogue.h" #include "subtitle_format_encore.h" + +#include "ass_dialogue.h" #include "text_file_writer.h" - -/// @brief Name -/// @return -/// -wxString EncoreSubtitleFormat::GetName() { - return "Adobe Encore"; +EncoreSubtitleFormat::EncoreSubtitleFormat() +: SubtitleFormat("Adobe Encore") +{ } - - -/// @brief Wildcards -/// @return -/// -wxArrayString EncoreSubtitleFormat::GetWriteWildcards() { +wxArrayString EncoreSubtitleFormat::GetWriteWildcards() const { wxArrayString formats; formats.Add("encore.txt"); return formats; } - - -/// @brief Can write file? -/// @param filename -/// @return -/// -bool EncoreSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Right(11).Lower() == ".encore.txt"); -} - - - -/// @brief Write file -/// @param _filename -/// @param encoding -/// -void EncoreSubtitleFormat::WriteFile(wxString _filename,wxString encoding) { - // Get FPS +void EncoreSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { FPSRational fps_rat = AskForFPS(true); if (fps_rat.num <= 0 || fps_rat.den <= 0) return; - // Open file - TextFileWriter file(_filename,encoding); + TextFileWriter file(filename, encoding); // Convert to encore CreateCopy(); @@ -92,25 +64,20 @@ void EncoreSubtitleFormat::WriteFile(wxString _filename,wxString encoding) { StripComments(); RecombineOverlaps(); MergeIdentical(); - ConvertTags(1,"\r\n"); + ConvertTags(1, "\r\n"); // Write lines - using std::list; int i = 0; // Encore wants ; instead of : if we're dealing with NTSC dropframe stuff FractionalTime ft(fps_rat.smpte_dropframe ? ";" : ":", fps_rat.num, fps_rat.den, fps_rat.smpte_dropframe); - for (list::iterator cur=Line->begin();cur!=Line->end();cur++) { - AssDialogue *current = dynamic_cast(*cur); - if (current && !current->Comment) { + for (std::list::iterator cur=Line->begin();cur!=Line->end();cur++) { + if (AssDialogue *current = dynamic_cast(*cur)) { ++i; file.WriteLineToFile(wxString::Format("%i %s %s %s", i, ft.FromAssTime(current->Start), ft.FromAssTime(current->End), current->Text)); } } - // Clean up ClearCopy(); } - - diff --git a/aegisub/src/subtitle_format_encore.h b/aegisub/src/subtitle_format_encore.h index 29e016c55..06c8a81ad 100644 --- a/aegisub/src/subtitle_format_encore.h +++ b/aegisub/src/subtitle_format_encore.h @@ -34,11 +34,6 @@ /// @ingroup subtitle_io /// - - - -/////////// -// Headers #include "subtitle_format.h" @@ -49,10 +44,7 @@ /// DOCME class EncoreSubtitleFormat : public SubtitleFormat { public: - wxString GetName(); - wxArrayString GetWriteWildcards(); - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + EncoreSubtitleFormat(); + wxArrayString GetWriteWildcards() const; + void WriteFile(wxString const& filename, wxString const& encoding); }; - - diff --git a/aegisub/src/subtitle_format_microdvd.cpp b/aegisub/src/subtitle_format_microdvd.cpp index 59d64b55b..74528e100 100644 --- a/aegisub/src/subtitle_format_microdvd.cpp +++ b/aegisub/src/subtitle_format_microdvd.cpp @@ -47,41 +47,38 @@ #include "text_file_writer.h" #include "video_context.h" -wxString MicroDVDSubtitleFormat::GetName() { - return "MicroDVD"; +MicroDVDSubtitleFormat::MicroDVDSubtitleFormat() +: SubtitleFormat("MicroDVD") +{ } -wxArrayString MicroDVDSubtitleFormat::GetReadWildcards() { +wxArrayString MicroDVDSubtitleFormat::GetReadWildcards() const { wxArrayString formats; formats.Add("sub"); return formats; } -wxArrayString MicroDVDSubtitleFormat::GetWriteWildcards() { +wxArrayString MicroDVDSubtitleFormat::GetWriteWildcards() const { return GetReadWildcards(); } -bool MicroDVDSubtitleFormat::CanReadFile(wxString filename) { +bool MicroDVDSubtitleFormat::CanReadFile(wxString const& filename) const { // Return false immediately if extension is wrong if (filename.Right(4).Lower() != ".sub") return false; // Since there is an infinity of .sub formats, load first line and check if it's valid TextFileReader file(filename); if (file.HasMoreLines()) { - wxRegEx exp("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$",wxRE_ADVANCED); + wxRegEx exp("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$", wxRE_ADVANCED); return exp.Matches(file.ReadLineFromFile()); } return false; } -bool MicroDVDSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Right(4).Lower() == ".sub"); -} - -void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) { +void MicroDVDSubtitleFormat::ReadFile(wxString const& filename, wxString const& forceEncoding) { TextFileReader file(filename); - wxRegEx exp("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$",wxRE_ADVANCED); + wxRegEx exp("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$", wxRE_ADVANCED); LoadDefault(false); @@ -94,10 +91,10 @@ void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) while (file.HasMoreLines()) { wxString line = file.ReadLineFromFile(); if (exp.Matches(line)) { - long f1,f2; - exp.GetMatch(line,1).ToLong(&f1); - exp.GetMatch(line,2).ToLong(&f2); - wxString text = exp.GetMatch(line,3); + long f1, f2; + exp.GetMatch(line, 1).ToLong(&f1); + exp.GetMatch(line, 2).ToLong(&f2); + wxString text = exp.GetMatch(line, 3); // If it's the first, check if it contains fps information if (isFirst) { @@ -123,25 +120,20 @@ void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) } } - // Start and end times - int start,end; - start = rate->TimeAtFrame(f1,agi::vfr::START); - end = rate->TimeAtFrame(f2,agi::vfr::END); + text.Replace("|", "\\N"); - text.Replace("|","\\N"); - - AssDialogue *line = new AssDialogue(); + AssDialogue *line = new AssDialogue; line->group = "[Events]"; line->Style = "Default"; - line->Start.SetMS(start); - line->End.SetMS(end); + line->Start.SetMS(rate->TimeAtFrame(f1, agi::vfr::START)); + line->End.SetMS(rate->TimeAtFrame(f2, agi::vfr::END)); line->Text = text; Line->push_back(line); } } } -void MicroDVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) { +void MicroDVDSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { agi::vfr::Framerate cfr; const agi::vfr::Framerate *rate = 𝔠 @@ -157,24 +149,22 @@ void MicroDVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) { StripComments(); RecombineOverlaps(); MergeIdentical(); - ConvertTags(1,"|"); + ConvertTags(1, "|"); - TextFileWriter file(filename,encoding); + TextFileWriter file(filename, encoding); // Write FPS line if (!rate->IsVFR()) { - file.WriteLineToFile(wxString::Format("{1}{1}%.6f",rate->FPS())); + file.WriteLineToFile(wxString::Format("{1}{1}%.6f", rate->FPS())); } // Write lines - using std::list; - for (list::iterator cur=Line->begin();cur!=Line->end();cur++) { - AssDialogue *current = dynamic_cast(*cur); - if (current && !current->Comment) { - int start = rate->FrameAtTime(current->Start.GetMS(),agi::vfr::START); - int end = rate->FrameAtTime(current->End.GetMS(),agi::vfr::END); + for (std::list::iterator cur=Line->begin();cur!=Line->end();cur++) { + if (AssDialogue *current = dynamic_cast(*cur)) { + int start = rate->FrameAtTime(current->Start.GetMS(), agi::vfr::START); + int end = rate->FrameAtTime(current->End.GetMS(), agi::vfr::END); - file.WriteLineToFile(wxString::Format("{%i}{%i}%s",start,end,current->Text)); + file.WriteLineToFile(wxString::Format("{%i}{%i}%s", start, end, current->Text)); } } diff --git a/aegisub/src/subtitle_format_microdvd.h b/aegisub/src/subtitle_format_microdvd.h index 5bf20b36a..7e311c115 100644 --- a/aegisub/src/subtitle_format_microdvd.h +++ b/aegisub/src/subtitle_format_microdvd.h @@ -43,13 +43,13 @@ /// DOCME class MicroDVDSubtitleFormat : public SubtitleFormat { public: - wxString GetName(); - wxArrayString GetReadWildcards(); - wxArrayString GetWriteWildcards(); + MicroDVDSubtitleFormat(); - bool CanReadFile(wxString filename); - void ReadFile(wxString filename,wxString forceEncoding); + wxArrayString GetReadWildcards() const; + wxArrayString GetWriteWildcards() const; - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + bool CanReadFile(wxString const& filename) const; + void ReadFile(wxString const& filename, wxString const& forceEncoding); + + void WriteFile(wxString const& filename, wxString const& encoding); }; diff --git a/aegisub/src/subtitle_format_mkv.cpp b/aegisub/src/subtitle_format_mkv.cpp index 7df1f1f30..715730ce4 100644 --- a/aegisub/src/subtitle_format_mkv.cpp +++ b/aegisub/src/subtitle_format_mkv.cpp @@ -34,44 +34,18 @@ /// @ingroup subtitle_io matroska /// - -/////////// -// Headers #include "config.h" -#include "ass_dialogue.h" -#include "ass_file.h" -#include "mkv_wrap.h" #include "subtitle_format_mkv.h" +#include "mkv_wrap.h" -/// @brief Can read? -/// @param filename -/// @return -/// -bool MKVSubtitleFormat::CanReadFile(wxString filename) { - if (filename.Right(4).Lower() == ".mkv" || filename.Right(4).Lower() == ".mks" - || filename.Right(4).Lower() == ".mka") - return true; - else - return false; +MKVSubtitleFormat::MKVSubtitleFormat() +: SubtitleFormat("Matroska") +{ } - - -/// @brief Get name -/// @return -/// -wxString MKVSubtitleFormat::GetName() { - return "Matroska"; -} - - - -/// @brief Get read wildcards -/// @return -/// -wxArrayString MKVSubtitleFormat::GetReadWildcards() { +wxArrayString MKVSubtitleFormat::GetReadWildcards() const { wxArrayString formats; formats.Add("mkv"); formats.Add("mka"); @@ -79,41 +53,8 @@ wxArrayString MKVSubtitleFormat::GetReadWildcards() { return formats; } - - -/// @brief Read file -/// @param filename -/// @param encoding -/// -void MKVSubtitleFormat::ReadFile(wxString filename,wxString encoding) { - // Open matroska +void MKVSubtitleFormat::ReadFile(wxString const& filename, wxString const& encoding) { MatroskaWrapper wrap; - wrap.Open(filename,false); - - // Read subtitles in a temporary object + wrap.Open(filename, false); wrap.GetSubtitles(GetAssFile()); - - // Close matroska - wrap.Close(); } - - - -/// @brief Can write to file? -/// @param filename -/// @return -/// -bool MKVSubtitleFormat::CanWriteFile(wxString filename) { - return false; -} - - - -/// @brief Write file -/// @param _filename -/// @param encoding -/// -void MKVSubtitleFormat::WriteFile(wxString _filename,wxString encoding) { -} - - diff --git a/aegisub/src/subtitle_format_mkv.h b/aegisub/src/subtitle_format_mkv.h index 8ef8d8dc4..cb6957fb9 100644 --- a/aegisub/src/subtitle_format_mkv.h +++ b/aegisub/src/subtitle_format_mkv.h @@ -34,19 +34,8 @@ /// @ingroup subtitle_io matroska /// - - - -/////////// -// Headers #include "subtitle_format.h" - -////////////// -// Prototypes -class AssDialogue; - - /// DOCME /// @class MKVSubtitleFormat /// @brief DOCME @@ -54,14 +43,8 @@ class AssDialogue; /// DOCME class MKVSubtitleFormat : public SubtitleFormat { public: - wxString GetName(); - wxArrayString GetReadWildcards(); + MKVSubtitleFormat(); + wxArrayString GetReadWildcards() const; - bool CanReadFile(wxString filename); - void ReadFile(wxString filename,wxString forceEncoding); - - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + void ReadFile(wxString const& filename, wxString const& forceEncoding); }; - - diff --git a/aegisub/src/subtitle_format_srt.cpp b/aegisub/src/subtitle_format_srt.cpp index c229b457c..19eaf957f 100644 --- a/aegisub/src/subtitle_format_srt.cpp +++ b/aegisub/src/subtitle_format_srt.cpp @@ -34,9 +34,6 @@ /// @ingroup subtitle_io /// - -/////////// -// Headers #include "config.h" #ifndef AGI_PRE @@ -52,67 +49,26 @@ DEFINE_SIMPLE_EXCEPTION(SRTParseError, SubtitleFormatParseError, "subtitle_io/parse/srt") - -/// @brief Can read? -/// @param filename -/// @return -/// -bool SRTSubtitleFormat::CanReadFile(wxString filename) { - return (filename.Right(4).Lower() == ".srt"); +SRTSubtitleFormat::SRTSubtitleFormat() +: SubtitleFormat("SubRip") +{ } - - -/// @brief Can write? -/// @param filename -/// @return -/// -bool SRTSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Right(4).Lower() == ".srt"); -} - - - -/// @brief Get name -/// @return -/// -wxString SRTSubtitleFormat::GetName() { - return "SubRip"; -} - - - -/// @brief Get read wildcards -/// @return -/// -wxArrayString SRTSubtitleFormat::GetReadWildcards() { +wxArrayString SRTSubtitleFormat::GetReadWildcards() const { wxArrayString formats; formats.Add("srt"); return formats; } - - -/// @brief Get write wildcards -/// @return -/// -wxArrayString SRTSubtitleFormat::GetWriteWildcards() { +wxArrayString SRTSubtitleFormat::GetWriteWildcards() const { return GetReadWildcards(); } - - -/// @brief Read file -/// @param filename -/// @param encoding -/// -void SRTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { +void SRTSubtitleFormat::ReadFile(wxString const& filename, wxString const& encoding) { using namespace std; - // Reader TextFileReader file(filename,encoding); - // Default LoadDefault(false); // See parsing algorithm at @@ -239,7 +195,7 @@ found_timestamps: } if (state == 1 || state == 2) { - throw SRTParseError(std::string("Parsing SRT: Incomplete file"), 0); + throw SRTParseError("Parsing SRT: Incomplete file", 0); } if (line) { @@ -248,15 +204,8 @@ found_timestamps: } } - - -/// @brief Write file -/// @param _filename -/// @param encoding -/// -void SRTSubtitleFormat::WriteFile(wxString _filename,wxString encoding) { - // Open file - TextFileWriter file(_filename,encoding); +void SRTSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { + TextFileWriter file(filename,encoding); // Convert to SRT CreateCopy(); @@ -274,22 +223,14 @@ void SRTSubtitleFormat::WriteFile(wxString _filename,wxString encoding) { // Write lines int i=1; - using std::list; - for (list::iterator cur=Line->begin();cur!=Line->end();cur++) { - AssDialogue *current = dynamic_cast(*cur); - if (current && !current->Comment) { - // Write line - file.WriteLineToFile(wxString::Format("%i",i)); + for (std::list::iterator cur=Line->begin();cur!=Line->end();cur++) { + if (AssDialogue *current = dynamic_cast(*cur)) { + file.WriteLineToFile(wxString::Format("%i", i++)); file.WriteLineToFile(current->Start.GetSRTFormated() + " --> " + current->End.GetSRTFormated()); file.WriteLineToFile(current->Text); file.WriteLineToFile(""); - - i++; } } - // Clean up ClearCopy(); } - - diff --git a/aegisub/src/subtitle_format_srt.h b/aegisub/src/subtitle_format_srt.h index 1280e4cb8..4ed9ad2da 100644 --- a/aegisub/src/subtitle_format_srt.h +++ b/aegisub/src/subtitle_format_srt.h @@ -34,20 +34,8 @@ /// @ingroup subtitle_io /// - - - -/////////// -// Headers #include "subtitle_format.h" - -////////////// -// Prototypes -class AssDialogue; - - - /// DOCME /// @class SRTSubtitleFormat /// @brief DOCME @@ -55,15 +43,10 @@ class AssDialogue; /// DOCME class SRTSubtitleFormat : public SubtitleFormat { public: - wxString GetName(); - wxArrayString GetReadWildcards(); - wxArrayString GetWriteWildcards(); + SRTSubtitleFormat(); + wxArrayString GetReadWildcards() const; + wxArrayString GetWriteWildcards() const; - bool CanReadFile(wxString filename); - void ReadFile(wxString filename,wxString forceEncoding); - - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + void ReadFile(wxString const& filename, wxString const& forceEncoding); + void WriteFile(wxString const& filename, wxString const& encoding); }; - - diff --git a/aegisub/src/subtitle_format_transtation.cpp b/aegisub/src/subtitle_format_transtation.cpp index f1733e08e..34ade8f2b 100644 --- a/aegisub/src/subtitle_format_transtation.cpp +++ b/aegisub/src/subtitle_format_transtation.cpp @@ -34,65 +34,36 @@ /// @ingroup subtitle_io /// - -/////////// -// Headers #include "config.h" #ifndef AGI_PRE #include #endif +#include "subtitle_format_transtation.h" + #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" #include "ass_time.h" -#include "subtitle_format_transtation.h" #include "text_file_writer.h" - -/// @brief Name -/// @return -/// -wxString TranStationSubtitleFormat::GetName() { - return "TranStation"; +TranStationSubtitleFormat::TranStationSubtitleFormat() +: SubtitleFormat("TranStation") +{ } - - -/// @brief Wildcards -/// @return -/// -wxArrayString TranStationSubtitleFormat::GetWriteWildcards() { +wxArrayString TranStationSubtitleFormat::GetWriteWildcards() const { wxArrayString formats; formats.Add("transtation.txt"); return formats; } - - -/// @brief Can write file? -/// @param filename -/// @return -/// -bool TranStationSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Right(16).Lower() == ".transtation.txt"); -} - - - -/// @brief Write file -/// @param _filename -/// @param encoding -/// @return -/// -void TranStationSubtitleFormat::WriteFile(wxString _filename,wxString encoding) { - // Get FPS +void TranStationSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { FPSRational fps_rat = AskForFPS(true); if (fps_rat.num <= 0 || fps_rat.den <= 0) return; - // Open file - TextFileWriter file(_filename,encoding); + TextFileWriter file(filename, encoding); // Convert to TranStation CreateCopy(); @@ -101,45 +72,34 @@ void TranStationSubtitleFormat::WriteFile(wxString _filename,wxString encoding) RecombineOverlaps(); MergeIdentical(); - // Write lines - using std::list; - AssDialogue *current = NULL; - AssDialogue *next = NULL; - for (list::iterator cur=Line->begin();cur!=Line->end();cur++) { - if (next) - current = next; - next = dynamic_cast(*cur); + AssDialogue *prev = 0; + for (std::list::iterator it = Line->begin(); it != Line->end(); ++it) { + AssDialogue *cur = dynamic_cast(*it); - if (current && !current->Comment) { - // Write text - file.WriteLineToFile(ConvertLine(current,&fps_rat,(next && !next->Comment) ? next->Start.GetMS() : -1)); + if (prev && cur) { + file.WriteLineToFile(ConvertLine(prev, &fps_rat, cur->Start.GetMS())); file.WriteLineToFile(""); } + + if (cur) + prev = cur; } + // flush last line - if (next && !next->Comment) - file.WriteLineToFile(ConvertLine(next,&fps_rat,-1)); + if (prev) + file.WriteLineToFile(ConvertLine(prev, &fps_rat, -1)); // Every file must end with this line file.WriteLineToFile("SUB["); - // Clean up ClearCopy(); } - -/// @brief DOCME -/// @param current -/// @param fps_rat -/// @param nextl_start -/// wxString TranStationSubtitleFormat::ConvertLine(AssDialogue *current, FPSRational *fps_rat, int nextl_start) { - // Get line data - AssStyle *style = GetAssFile()->GetStyle(current->Style); int valign = 0; const char *halign = " "; // default is centered const char *type = "N"; // no special style - if (style) { + if (AssStyle *style = GetAssFile()->GetStyle(current->Style)) { if (style->alignment >= 4) valign = 4; if (style->alignment >= 7) valign = 9; if (style->alignment == 1 || style->alignment == 4 || style->alignment == 7) halign = "L"; @@ -162,16 +122,15 @@ wxString TranStationSubtitleFormat::ConvertLine(AssDialogue *current, FPSRationa end.SetMS(end.GetMS() - ((1000*fps_rat->den)/fps_rat->num)); FractionalTime ft(":", fps_rat->num, fps_rat->den, fps_rat->smpte_dropframe); - wxString header = wxString::Format("SUB[%i%s%s ",valign,halign,type) + ft.FromAssTime(start) + ">" + ft.FromAssTime(end) + "]\r\n"; + wxString header = wxString::Format("SUB[%i%s%s ", valign, halign, type) + ft.FromAssTime(start) + ">" + ft.FromAssTime(end) + "]\r\n"; // Process text wxString lineEnd = "\r\n"; current->StripTags(); - current->Text.Replace("\\h"," ",true); - current->Text.Replace("\\n",lineEnd,true); - current->Text.Replace("\\N",lineEnd,true); - while (current->Text.Replace(lineEnd+lineEnd,lineEnd,true)) {}; + current->Text.Replace("\\h", " ", true); + current->Text.Replace("\\n", lineEnd, true); + current->Text.Replace("\\N", lineEnd, true); + while (current->Text.Replace(lineEnd + lineEnd, lineEnd, true)); return header + current->Text; } - diff --git a/aegisub/src/subtitle_format_transtation.h b/aegisub/src/subtitle_format_transtation.h index 429da83d0..7dca80133 100644 --- a/aegisub/src/subtitle_format_transtation.h +++ b/aegisub/src/subtitle_format_transtation.h @@ -34,13 +34,9 @@ /// @ingroup subtitle_io /// - - - -/////////// -// Headers #include "subtitle_format.h" +class AssDialogue; /// DOCME /// @class TranStationSubtitleFormat @@ -48,14 +44,10 @@ /// /// DOCME class TranStationSubtitleFormat : public SubtitleFormat { -private: wxString ConvertLine(AssDialogue *line, FPSRational *fps_rat, int nextl_start); public: - wxString GetName(); - wxArrayString GetWriteWildcards(); - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + TranStationSubtitleFormat(); + wxArrayString GetWriteWildcards() const; + void WriteFile(wxString const& filename, wxString const& encoding); }; - - diff --git a/aegisub/src/subtitle_format_ttxt.cpp b/aegisub/src/subtitle_format_ttxt.cpp index f0cfb7eff..363ce763d 100644 --- a/aegisub/src/subtitle_format_ttxt.cpp +++ b/aegisub/src/subtitle_format_ttxt.cpp @@ -34,90 +34,49 @@ /// @ingroup subtitle_io /// - -/////////// -// Headers #include "config.h" +#include "subtitle_format_ttxt.h" + +#include "ass_dialogue.h" #include "ass_file.h" #include "ass_time.h" #include "compat.h" #include "main.h" -#include "subtitle_format_ttxt.h" +DEFINE_SIMPLE_EXCEPTION(TTXTParseError, SubtitleFormatParseError, "subtitle_io/parse/ttxt") -/// @brief Get format name -/// @return -/// -wxString TTXTSubtitleFormat::GetName() { - return "MPEG-4 Streaming Text"; +TTXTSubtitleFormat::TTXTSubtitleFormat() +: SubtitleFormat("MPEG-4 Streaming Text") +{ } - - -/// @brief Get read wildcards -/// @return -/// -wxArrayString TTXTSubtitleFormat::GetReadWildcards() { +wxArrayString TTXTSubtitleFormat::GetReadWildcards() const { wxArrayString formats; formats.Add("ttxt"); return formats; } - - -/// @brief Get write wildcards -/// @return -/// -wxArrayString TTXTSubtitleFormat::GetWriteWildcards() { +wxArrayString TTXTSubtitleFormat::GetWriteWildcards() const { return GetReadWildcards(); - //return wxArrayString(); } - - -/// @brief Can read a file? -/// @param filename -/// @return -/// -bool TTXTSubtitleFormat::CanReadFile(wxString filename) { - return (filename.Right(5).Lower() == ".ttxt"); -} - - - -/// @brief Can write a file? -/// @param filename -/// @return -/// -bool TTXTSubtitleFormat::CanWriteFile(wxString filename) { - //return false; - return (filename.Right(5).Lower() == ".ttxt"); -} - - - -/// @brief Read a file -/// @param filename -/// @param forceEncoding -/// -void TTXTSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) { - // Load default +void TTXTSubtitleFormat::ReadFile(wxString const& filename, wxString const& forceEncoding) { LoadDefault(false); // Load XML document wxXmlDocument doc; - if (!doc.Load(filename)) throw "Failed loading TTXT XML file."; + if (!doc.Load(filename)) throw TTXTParseError("Failed loading TTXT XML file.", 0); // Check root node name - if (doc.GetRoot()->GetName() != "TextStream") throw "Invalid TTXT file."; + if (doc.GetRoot()->GetName() != "TextStream") throw TTXTParseError("Invalid TTXT file.", 0); // Check version - wxString verStr = doc.GetRoot()->GetAttribute("version",""); + wxString verStr = doc.GetRoot()->GetAttribute("version", ""); version = -1; if (verStr == "1.0") version = 0; else if (verStr == "1.1") version = 1; - else throw wxString("Unknown TTXT version: " + verStr); + else throw TTXTParseError("Unknown TTXT version: " + STD_STR(verStr), 0); // Get children diag = NULL; @@ -149,15 +108,9 @@ void TTXTSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) { } } - - -/// @brief Process a dialogue line -/// @param node -/// @return -/// bool TTXTSubtitleFormat::ProcessLine(wxXmlNode *node) { // Get time - wxString sampleTime = node->GetAttribute("sampleTime","00:00:00.000"); + wxString sampleTime = node->GetAttribute("sampleTime", "00:00:00.000"); AssTime time; time.ParseASS(sampleTime); @@ -167,7 +120,7 @@ bool TTXTSubtitleFormat::ProcessLine(wxXmlNode *node) { // Get text wxString text; - if (version == 0) text = node->GetAttribute("text",""); + if (version == 0) text = node->GetAttribute("text", ""); else text = node->GetNodeContent(); // Create line @@ -199,8 +152,8 @@ bool TTXTSubtitleFormat::ProcessLine(wxXmlNode *node) { // Process text for 1.1 else { - text.Replace("\r",""); - text.Replace("\n","\\N"); + text.Replace("\r", ""); + text.Replace("\n", "\\N"); diag->Text = text; } @@ -212,30 +165,19 @@ bool TTXTSubtitleFormat::ProcessLine(wxXmlNode *node) { else return false; } - - -/// @brief Process the header -/// @param node -/// void TTXTSubtitleFormat::ProcessHeader(wxXmlNode *node) { // TODO } - - -/// @brief Write a file -/// @param filename -/// @param encoding -/// -void TTXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { +void TTXTSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { // Convert to TTXT CreateCopy(); ConvertToTTXT(); // Create XML structure wxXmlDocument doc; - wxXmlNode *root = new wxXmlNode(NULL,wxXML_ELEMENT_NODE,"TextStream"); - root->AddAttribute("version","1.1"); + wxXmlNode *root = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, "TextStream"); + root->AddAttribute("version", "1.1"); doc.SetRoot(root); // Create header @@ -248,10 +190,11 @@ void TTXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { for (list::iterator cur=Line->begin();cur!=Line->end();cur++) { AssDialogue *current = dynamic_cast(*cur); if (current && !current->Comment) { - WriteLine(root,current); + WriteLine(root, current); i++; } - else throw "Unexpected line type in TTXT file"; + else + throw TTXTParseError("Unexpected line type in TTXT file", 0); } // Save XML @@ -262,82 +205,71 @@ void TTXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { ClearCopy(); } - - -/// @brief Write header -/// @param root -/// void TTXTSubtitleFormat::WriteHeader(wxXmlNode *root) { // Write stream header - wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE,"TextStreamHeader"); - node->AddAttribute("width","400"); - node->AddAttribute("height","60"); - node->AddAttribute("layer","0"); - node->AddAttribute("translation_x","0"); - node->AddAttribute("translation_y","0"); + wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, "TextStreamHeader"); + node->AddAttribute("width", "400"); + node->AddAttribute("height", "60"); + node->AddAttribute("layer", "0"); + node->AddAttribute("translation_x", "0"); + node->AddAttribute("translation_y", "0"); root->AddChild(node); root = node; // Write sample description - node = new wxXmlNode(wxXML_ELEMENT_NODE,"TextSampleDescription"); - node->AddAttribute("horizontalJustification","center"); - node->AddAttribute("verticalJustification","bottom"); - node->AddAttribute("backColor","0 0 0 0"); - node->AddAttribute("verticalText","no"); - node->AddAttribute("fillTextRegion","no"); - node->AddAttribute("continuousKaraoke","no"); - node->AddAttribute("scroll","None"); + node = new wxXmlNode(wxXML_ELEMENT_NODE, "TextSampleDescription"); + node->AddAttribute("horizontalJustification", "center"); + node->AddAttribute("verticalJustification", "bottom"); + node->AddAttribute("backColor", "0 0 0 0"); + node->AddAttribute("verticalText", "no"); + node->AddAttribute("fillTextRegion", "no"); + node->AddAttribute("continuousKaraoke", "no"); + node->AddAttribute("scroll", "None"); root->AddChild(node); root = node; // Write font table - node = new wxXmlNode(wxXML_ELEMENT_NODE,"FontTable"); - wxXmlNode *subNode = new wxXmlNode(wxXML_ELEMENT_NODE,"FontTableEntry"); - subNode->AddAttribute("fontName","Sans"); - subNode->AddAttribute("fontID","1"); + node = new wxXmlNode(wxXML_ELEMENT_NODE, "FontTable"); + wxXmlNode *subNode = new wxXmlNode(wxXML_ELEMENT_NODE, "FontTableEntry"); + subNode->AddAttribute("fontName", "Sans"); + subNode->AddAttribute("fontID", "1"); node->AddChild(subNode); root->AddChild(node); // Write text box - node = new wxXmlNode(wxXML_ELEMENT_NODE,"TextBox"); - node->AddAttribute("top","0"); - node->AddAttribute("left","0"); - node->AddAttribute("bottom","60"); - node->AddAttribute("right","400"); + node = new wxXmlNode(wxXML_ELEMENT_NODE, "TextBox"); + node->AddAttribute("top", "0"); + node->AddAttribute("left", "0"); + node->AddAttribute("bottom", "60"); + node->AddAttribute("right", "400"); root->AddChild(node); // Write style - node = new wxXmlNode(wxXML_ELEMENT_NODE,"Style"); - node->AddAttribute("styles","Normal"); - node->AddAttribute("fontID","1"); - node->AddAttribute("fontSize","18"); - node->AddAttribute("color","ff ff ff ff"); + node = new wxXmlNode(wxXML_ELEMENT_NODE, "Style"); + node->AddAttribute("styles", "Normal"); + node->AddAttribute("fontID", "1"); + node->AddAttribute("fontSize", "18"); + node->AddAttribute("color", "ff ff ff ff"); root->AddChild(node); } - - -/// @brief Write line -/// @param root -/// @param line -/// void TTXTSubtitleFormat::WriteLine(wxXmlNode *root, AssDialogue *line) { // If it doesn't start at the end of previous, add blank - wxXmlNode *node,*subNode; + wxXmlNode *node, *subNode; if (prev && prev->End != line->Start) { - node = new wxXmlNode(wxXML_ELEMENT_NODE,"TextSample"); - node->AddAttribute("sampleTime","0" + prev->End.GetASSFormated(true)); - node->AddAttribute("xml:space","preserve"); - subNode = new wxXmlNode(wxXML_TEXT_NODE,"",""); + node = new wxXmlNode(wxXML_ELEMENT_NODE, "TextSample"); + node->AddAttribute("sampleTime", "0" + prev->End.GetASSFormated(true)); + node->AddAttribute("xml:space", "preserve"); + subNode = new wxXmlNode(wxXML_TEXT_NODE, "", ""); node->AddChild(subNode); root->AddChild(node); } // Generate and insert node - node = new wxXmlNode(wxXML_ELEMENT_NODE,"TextSample"); - node->AddAttribute("sampleTime","0" + line->Start.GetASSFormated(true)); - node->AddAttribute("xml:space","preserve"); - subNode = new wxXmlNode(wxXML_TEXT_NODE,"",line->Text); + node = new wxXmlNode(wxXML_ELEMENT_NODE, "TextSample"); + node->AddAttribute("sampleTime", "0" + line->Start.GetASSFormated(true)); + node->AddAttribute("xml:space", "preserve"); + subNode = new wxXmlNode(wxXML_TEXT_NODE, "", line->Text); node->AddChild(subNode); root->AddChild(node); @@ -345,17 +277,12 @@ void TTXTSubtitleFormat::WriteLine(wxXmlNode *root, AssDialogue *line) { prev = line; } - - -/// @brief Converts whole file to TTXT -/// void TTXTSubtitleFormat::ConvertToTTXT () { - // Convert SortLines(); StripComments(); RecombineOverlaps(); MergeIdentical(); - ConvertTags(1,"\r\n"); + ConvertTags(1, "\r\n"); // Find last line AssTime lastTime; @@ -376,5 +303,3 @@ void TTXTSubtitleFormat::ConvertToTTXT () { diag->Comment = false; Line->push_back(diag); } - - diff --git a/aegisub/src/subtitle_format_ttxt.h b/aegisub/src/subtitle_format_ttxt.h index 98f444872..d1819433b 100644 --- a/aegisub/src/subtitle_format_ttxt.h +++ b/aegisub/src/subtitle_format_ttxt.h @@ -34,18 +34,14 @@ /// @ingroup subtitle_io /// - - - -/////////// -// Headers #ifndef AGI_PRE #include #endif -#include "ass_dialogue.h" #include "subtitle_format.h" +class AssDialogue; + /// DOCME /// @class TTXTSubtitleFormat @@ -53,8 +49,6 @@ /// /// DOCME class TTXTSubtitleFormat : public SubtitleFormat { -private: - /// DOCME int version; @@ -68,20 +62,15 @@ private: void ProcessHeader(wxXmlNode *node); void WriteHeader(wxXmlNode *root); - void WriteLine(wxXmlNode *root,AssDialogue *line); + void WriteLine(wxXmlNode *root, AssDialogue *line); void ConvertToTTXT(); public: - wxString GetName(); - wxArrayString GetReadWildcards(); - wxArrayString GetWriteWildcards(); + TTXTSubtitleFormat(); + wxArrayString GetReadWildcards() const; + wxArrayString GetWriteWildcards() const; - bool CanReadFile(wxString filename); - void ReadFile(wxString filename,wxString forceEncoding); - - bool CanWriteFile(wxString filename); - void WriteFile(wxString filename,wxString encoding); + void ReadFile(wxString const& filename, wxString const& forceEncoding); + void WriteFile(wxString const& filename, wxString const& encoding); }; - - diff --git a/aegisub/src/subtitle_format_txt.cpp b/aegisub/src/subtitle_format_txt.cpp index 53d5470a8..ed39171be 100644 --- a/aegisub/src/subtitle_format_txt.cpp +++ b/aegisub/src/subtitle_format_txt.cpp @@ -34,114 +34,70 @@ /// @ingroup subtitle_io /// - -/////////// -// Headers #include "config.h" +#include "subtitle_format_txt.h" + #include "ass_dialogue.h" #include "compat.h" #include "dialog_text_import.h" #include "main.h" -#include "subtitle_format_txt.h" #include "text_file_reader.h" #include "text_file_writer.h" #include "version.h" -/// @brief Can read? -/// @param filename -/// @return -/// -bool TXTSubtitleFormat::CanReadFile(wxString filename) { - return (filename.Right(4).Lower() == ".txt"); +TXTSubtitleFormat::TXTSubtitleFormat() +: SubtitleFormat("Plain-Text") +{ } - - -/// @brief Can write? -/// @param filename -/// @return -/// -bool TXTSubtitleFormat::CanWriteFile(wxString filename) { - return (filename.Right(4).Lower() == ".txt" && filename.Right(11).Lower() != ".encore.txt" && filename.Right(16).Lower() != ".transtation.txt"); -} - - - -/// @brief Get name -/// @return -/// -wxString TXTSubtitleFormat::GetName() { - return "Plain-Text"; -} - - - -/// @brief Get read wildcards -/// @return -/// -wxArrayString TXTSubtitleFormat::GetReadWildcards() { +wxArrayString TXTSubtitleFormat::GetReadWildcards() const { wxArrayString formats; formats.Add("txt"); return formats; } - - -/// @brief Get write wildcards -/// @return -/// -wxArrayString TXTSubtitleFormat::GetWriteWildcards() { +wxArrayString TXTSubtitleFormat::GetWriteWildcards() const { return GetReadWildcards(); } +bool TXTSubtitleFormat::CanWriteFile(wxString const& filename) const { + return (filename.Right(4).Lower() == ".txt" && filename.Right(11).Lower() != ".encore.txt" && filename.Right(16).Lower() != ".transtation.txt"); +} - -/// @brief Read file -/// @param filename -/// @param encoding -/// @return -/// -void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { using namespace std; - // Import options +void TXTSubtitleFormat::ReadFile(wxString const& filename, wxString const& encoding) { + using namespace std; DialogTextImport dlg; if (dlg.ShowModal() == wxID_CANCEL) return; - // Reader - TextFileReader file(filename,encoding,false); + TextFileReader file(filename, encoding, false); - // Default LoadDefault(false); - // Data wxString actor; wxString separator = lagi_wxString(OPT_GET("Tool/Import/Text/Actor Separator")->GetString()); wxString comment = lagi_wxString(OPT_GET("Tool/Import/Text/Comment Starter")->GetString()); - bool isComment = false; int lines = 0; // Parse file - AssDialogue *line = NULL; while (file.HasMoreLines()) { - // Reads line wxString value = file.ReadLineFromFile(); - if(value.IsEmpty()) continue; + if(value.empty()) continue; // Check if this isn't a timecodes file - if (value.StartsWith("# timecode")) { - throw "File is a timecode file, cannot load as subtitles."; - } + if (value.StartsWith("# timecode")) + throw SubtitleFormatParseError("File is a timecode file, cannot load as subtitles.", 0); // Read comment data - isComment = false; - if (comment != "" && value.Left(comment.Length()) == comment) { + bool isComment = false; + if (!comment.empty() && value.StartsWith(comment)) { isComment = true; - value = value.Mid(comment.Length()); + value = value.Mid(comment.size()); } // Read actor data - if (!isComment && separator != "") { + if (!isComment && !separator.empty()) { if (value[0] != ' ' && value[0] != '\t') { int pos = value.Find(separator); if (pos != wxNOT_FOUND) { @@ -149,7 +105,6 @@ void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { using na actor.Trim(false); actor.Trim(true); value = value.Mid(pos+1); - value.Trim(false); } } } @@ -157,16 +112,14 @@ void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { using na // Trim spaces at start value.Trim(false); + if (value.empty()) + isComment = true; + // Sets line up - line = new AssDialogue; + AssDialogue *line = new AssDialogue; line->group = "[Events]"; line->Style = "Default"; - if (isComment) line->Actor = ""; - else line->Actor = actor; - if (value.IsEmpty()) { - line->Actor = ""; - isComment = true; - } + line->Actor = isComment ? "" : line->Actor; line->Comment = isComment; line->Text = value; line->Start.SetMS(0); @@ -179,7 +132,7 @@ void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { using na // No lines? if (lines == 0) { - line = new AssDialogue; + AssDialogue *line = new AssDialogue; line->group = "[Events]"; line->Style = "Default"; line->Start.SetMS(0); @@ -188,21 +141,15 @@ void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { using na } } - - -/// @brief Write file -/// @param filename -/// @param encoding -/// -void TXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { using namespace std; +void TXTSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) { size_t num_actor_names = 0, num_dialogue_lines = 0; // Detect number of lines with Actor field filled out - for (list::iterator l = Line->begin(); l != Line->end(); ++l) { + for (std::list::iterator l = Line->begin(); l != Line->end(); ++l) { AssDialogue *dia = dynamic_cast(*l); if (dia && !dia->Comment) { num_dialogue_lines++; - if (!dia->Actor.IsEmpty()) + if (!dia->Actor.empty()) num_actor_names++; } } @@ -215,7 +162,7 @@ void TXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { using n file.WriteLineToFile(wxString("# Exported by Aegisub ") + GetAegisubShortVersionString()); // Write the file - for (list::iterator l = Line->begin(); l != Line->end(); ++l) { + for (std::list::iterator l = Line->begin(); l != Line->end(); ++l) { AssDialogue *dia = dynamic_cast(*l); if (dia) { @@ -244,7 +191,7 @@ void TXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { using n } out_line += out_text; - if (!out_text.IsEmpty()) { + if (!out_text.empty()) { file.WriteLineToFile(out_line); } } @@ -255,5 +202,3 @@ void TXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { using n } } } - - diff --git a/aegisub/src/subtitle_format_txt.h b/aegisub/src/subtitle_format_txt.h index d04e61972..c8431fa20 100644 --- a/aegisub/src/subtitle_format_txt.h +++ b/aegisub/src/subtitle_format_txt.h @@ -34,36 +34,20 @@ /// @ingroup subtitle_io /// - - - -/////////// -// Headers #include "subtitle_format.h" - -////////////// -// Prototypes -class AssDialogue; - - /// DOCME /// @class TXTSubtitleFormat /// @brief DOCME /// /// DOCME class TXTSubtitleFormat : public SubtitleFormat { -private: - public: - wxString GetName(); - wxArrayString GetReadWildcards(); - wxArrayString GetWriteWildcards(); + TXTSubtitleFormat(); + wxArrayString GetReadWildcards() const; + wxArrayString GetWriteWildcards() const; - bool CanReadFile(wxString filename); - bool CanWriteFile(wxString filename); - void ReadFile(wxString filename,wxString forceEncoding); - void WriteFile(wxString filename, wxString encoding = ""); + bool CanWriteFile(wxString const& filename) const; + void ReadFile(wxString const& filename, wxString const& forceEncoding); + void WriteFile(wxString const& filename, wxString const& encoding); }; - -