Clean up SubtitleFormat

Document all of the SubtitleFormat methods.

Add default implementations of CanReadFile and CanWriteFile that check
against the appropriate wildcard list.

Clean up and simplify a lot of very odd code.

Throw typed exceptions in all subtitle readers rather than strings.

Originally committed to SVN as r5617.
This commit is contained in:
Thomas Goyne 2011-09-28 19:44:53 +00:00
parent 156885b56d
commit 4ec507f814
22 changed files with 511 additions and 1182 deletions

View file

@ -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);

View file

@ -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

View file

@ -41,6 +41,7 @@
#include <wx/choicdlg.h> // 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*> 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<SubtitleFormat*>::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<SubtitleFormat*>::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<SubtitleFormat*>::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<SubtitleFormat*>::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<SubtitleFormat*>::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<SubtitleFormat*>::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;i<cur.Count();i++) {
wild = "*." + cur[i];
all.Add(wild);
temp1 += wild + ",";
temp2 += wild + ";";
}
// Assemble final name
final += format->GetName() + " (" + temp1.Left(temp1.Length()-1) + ")|" + temp2.Left(temp2.Length()-1) + "|";
}
}
// Add "all formats" list
temp1.Clear();
temp2.Clear();
for (unsigned int i=0;i<all.Count();i++) {
temp1 += all[i] + ",";
temp2 += all[i] + ";";
}
final = wxString(_("All Supported Formats")) + " (" + temp1.Left(temp1.Length()-1) + ")|" + temp2.Left(temp2.Length()-1) + "|" + final.Left(final.Length()-1);
// Return final list
return final;
void SubtitleFormat::AddLine(wxString data, wxString group, int &version, wxString *outgroup) {
assFile->AddLine(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<AssEntry*>::iterator next;
for (list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
AssDialogue *current = dynamic_cast<AssDialogue*>(*cur);
if (current) {
void SubtitleFormat::ConvertTags(int format, const wxString &lineEnd, bool mergeLineBreaks) {
for (std::list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); ++cur) {
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*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<AssEntry*>::iterator next;
for (list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); cur = next) {
next = cur;
next++;
AssDialogue *dlg = dynamic_cast<AssDialogue*>(*cur);
if (dlg && (dlg->Comment || dlg->Text.IsEmpty())) {
delete *cur;
Line->erase(cur);
for (std::list<AssEntry*>::iterator it = Line->begin(); it != Line->end(); ) {
AssDialogue *diag = dynamic_cast<AssDialogue*>(*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<AssEntry*>::iterator next;
for (list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); cur = next) {
next = cur;
next++;
if (!dynamic_cast<AssDialogue*>(*cur)) {
delete *cur;
Line->erase(cur);
for (std::list<AssEntry*>::iterator it = Line->begin(); it != Line->end(); ) {
if (dynamic_cast<AssDialogue*>(*it))
++it;
else {
delete *it;
Line->erase(it++);
}
}
}
/// @brief Helper function for RecombineOverlaps()
/// @param list
/// @param next
/// @param newdlg
///
static void InsertLineSortedIntoList(std::list<AssEntry*> &list, std::list<AssEntry*>::iterator next, AssDialogue *newdlg) {
std::list<AssEntry*>::iterator insertpos = next;
bool inserted = false;
while (insertpos != list.end()) {
AssDialogue *candidate = dynamic_cast<AssDialogue*>(*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<AssDialogue*>(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<AssEntry*>::iterator next;
for (list<AssEntry*>::iterator cur = Line->begin(); cur != Line->end(); cur = next) {
next = cur;
next++;
if (next == Line->end()) break;
std::list<AssEntry*>::iterator cur, next = Line->begin();
cur = next++;
for (; next != Line->end(); cur = next++) {
AssDialogue *prevdlg = dynamic_cast<AssDialogue*>(*cur);
AssDialogue *curdlg = dynamic_cast<AssDialogue*>(*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<AssEntry*>::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<AssDialogue*>(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<AssDialogue*>(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<AssDialogue*>(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<AssDialogue*>(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<AssEntry*>::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<AssDialogue*>(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<AssDialogue*>(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<AssDialogue*>(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<AssDialogue*>(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<AssEntry*>::iterator next;
std::list<AssEntry*>::iterator cur, next = Line->begin();
cur = next++;
for (list<AssEntry*>::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<AssDialogue*>(*cur);
AssDialogue *nextdlg = dynamic_cast<AssDialogue*>(*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*> 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<SubtitleFormat*>::iterator it = formats.begin(); it != formats.end(); )
delete *it++;
}
template<class Cont, class Pred>
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<SubtitleFormat*>::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;
}

View file

@ -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<SubtitleFormat*> formats;
/// DOCME
static bool loaded;
protected:
/// DOCME
struct FPSRational {
/// DOCME
int num;
/// DOCME
int den;
/// DOCME
bool smpte_dropframe;
};
/// DOCME
std::list<AssEntry*> *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();
};

View file

@ -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<AssEntry*>::iterator last = Line->end(); --last;
wxString group = Line->front()->group;
for (std::list<AssEntry*>::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);
}
}

View file

@ -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);
};

View file

@ -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 <omp.h>
@ -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<SubPicture> &pics) {
// Create video frame
int w = 720;
@ -361,7 +334,7 @@ void DVDSubtitleFormat::GetSubPictureList(std::vector<SubPicture> &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();

View file

@ -34,18 +34,12 @@
/// @ingroup subtitle_io vobsub
///
///////////
// Headers
#ifndef AGI_PRE
#include <vector>
#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<SubPicture> &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);
};

View file

@ -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<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
AssDialogue *current = dynamic_cast<AssDialogue*>(*cur);
if (current && !current->Comment) {
for (std::list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*cur)) {
++i;
file.WriteLineToFile(wxString::Format("%i %s %s %s", i, ft.FromAssTime(current->Start), ft.FromAssTime(current->End), current->Text));
}
}
// Clean up
ClearCopy();
}

View file

@ -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);
};

View file

@ -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 = &cfr;
@ -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<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
AssDialogue *current = dynamic_cast<AssDialogue*>(*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<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*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));
}
}

View file

@ -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);
};

View file

@ -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) {
}

View file

@ -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);
};

View file

@ -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 <http://devel.aegisub.org/wiki/SubtitleFormats/SRT>
@ -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<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
AssDialogue *current = dynamic_cast<AssDialogue*>(*cur);
if (current && !current->Comment) {
// Write line
file.WriteLineToFile(wxString::Format("%i",i));
for (std::list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
if (AssDialogue *current = dynamic_cast<AssDialogue*>(*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();
}

View file

@ -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);
};

View file

@ -34,65 +34,36 @@
/// @ingroup subtitle_io
///
///////////
// Headers
#include "config.h"
#ifndef AGI_PRE
#include <stdio.h>
#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<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
if (next)
current = next;
next = dynamic_cast<AssDialogue*>(*cur);
AssDialogue *prev = 0;
for (std::list<AssEntry*>::iterator it = Line->begin(); it != Line->end(); ++it) {
AssDialogue *cur = dynamic_cast<AssDialogue*>(*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;
}

View file

@ -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);
};

View file

@ -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<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
AssDialogue *current = dynamic_cast<AssDialogue*>(*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);
}

View file

@ -34,18 +34,14 @@
/// @ingroup subtitle_io
///
///////////
// Headers
#ifndef AGI_PRE
#include <wx/xml/xml.h>
#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);
};

View file

@ -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<AssEntry*>::iterator l = Line->begin(); l != Line->end(); ++l) {
for (std::list<AssEntry*>::iterator l = Line->begin(); l != Line->end(); ++l) {
AssDialogue *dia = dynamic_cast<AssDialogue*>(*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<AssEntry*>::iterator l = Line->begin(); l != Line->end(); ++l) {
for (std::list<AssEntry*>::iterator l = Line->begin(); l != Line->end(); ++l) {
AssDialogue *dia = dynamic_cast<AssDialogue*>(*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
}
}
}

View file

@ -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);
};