mirror of https://github.com/odrling/Aegisub
Finished new format system
Originally committed to SVN as r186.
This commit is contained in:
parent
32b284a27c
commit
ae8f256e78
|
@ -92,6 +92,7 @@ AssStyle *AssEntry::GetAsStyle(AssEntry *base) {
|
|||
//////////////////////
|
||||
// Get SSA conversion
|
||||
wxString AssEntry::GetSSAText() {
|
||||
// Special cases
|
||||
if (data.Lower() == _T("[v4+ styles]")) return wxString(_T("[V4 Styles]"));
|
||||
if (data.Lower() == _T("scripttype: v4.00+")) return wxString(_T("ScriptType: v4.00"));
|
||||
if (data.Lower().Left(7) == _T("format:")) {
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "text_file_reader.h"
|
||||
#include "text_file_writer.h"
|
||||
#include "version.h"
|
||||
#include "subtitle_format_reader.h"
|
||||
#include "subtitle_format.h"
|
||||
|
||||
|
||||
////////////////////// AssFile //////////////////////
|
||||
|
@ -92,7 +92,7 @@ void AssFile::Load (const wxString _filename,const wxString charset) {
|
|||
IsASS = false;
|
||||
|
||||
// Get proper format reader
|
||||
SubtitleFormatReader *reader = SubtitleFormatReader::GetReader(_filename);
|
||||
SubtitleFormat *reader = SubtitleFormat::GetReader(_filename);
|
||||
|
||||
// Read file
|
||||
if (reader) {
|
||||
|
@ -148,28 +148,20 @@ void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wx
|
|||
extension.Lower();
|
||||
bool success = false;
|
||||
|
||||
// ASS
|
||||
if (extension == _T("ass")) {
|
||||
SaveASS(_filename,encoding);
|
||||
if (addToRecent) AddToRecent(_filename);
|
||||
success = true;
|
||||
// Get writer
|
||||
SubtitleFormat *writer = SubtitleFormat::GetWriter(_filename);
|
||||
|
||||
// Write file
|
||||
if (writer) {
|
||||
writer->SetTarget(this);
|
||||
writer->WriteFile(_filename,encoding);
|
||||
}
|
||||
|
||||
// SSA
|
||||
if (extension == _T("ssa")) {
|
||||
AssFile SSA(*this);
|
||||
SSA.SaveSSA(_filename,encoding);
|
||||
if (addToRecent) AddToRecent(_filename);
|
||||
success = true;
|
||||
}
|
||||
// Couldn't find a type
|
||||
else throw _T("Unknown file type.");
|
||||
|
||||
// SRT
|
||||
if (extension == _T("srt")) {
|
||||
AssFile SRT(*this);
|
||||
SRT.SaveSRT(_filename,encoding);
|
||||
// Add to recent
|
||||
if (addToRecent) AddToRecent(_filename);
|
||||
success = true;
|
||||
}
|
||||
|
||||
// Done
|
||||
if (setfilename) {
|
||||
|
@ -177,9 +169,6 @@ void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wx
|
|||
filename = _filename;
|
||||
IsASS = true;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
if (!success) throw _T("Unknown file type");
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,151 +181,6 @@ void AssFile::Export(wxString _filename) {
|
|||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Saves ASS to disk
|
||||
void AssFile::SaveASS (wxString _filename,const wxString encoding) {
|
||||
// Open file
|
||||
TextFileWriter file(_filename,encoding);
|
||||
|
||||
// Write lines
|
||||
using std::list;
|
||||
for (list<AssEntry*>::iterator cur=Line.begin();cur!=Line.end();cur++) {
|
||||
file.WriteLineToFile((*cur)->GetEntryData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Saves SSA to disk
|
||||
void AssFile::SaveSSA (wxString _filename,const wxString encoding) {
|
||||
// Open file
|
||||
TextFileWriter file(_filename,encoding);
|
||||
|
||||
// Convert to SSA
|
||||
ConvertToSSA();
|
||||
|
||||
// Write lines
|
||||
using std::list;
|
||||
for (list<AssEntry*>::iterator cur=Line.begin();cur!=Line.end();cur++) {
|
||||
file.WriteLineToFile((*cur)->GetSSAText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Convert to SSA
|
||||
void AssFile::ConvertToSSA () {
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// Save SRT to disk
|
||||
// ----------------
|
||||
// Note that this function will convert the whole AssFile to SRT
|
||||
//
|
||||
void AssFile::SaveSRT (wxString _filename,const wxString encoding) {
|
||||
// Open file
|
||||
TextFileWriter file(_filename,encoding);
|
||||
|
||||
// Convert to SRT
|
||||
ConvertToSRT();
|
||||
|
||||
// Write lines
|
||||
int i=1;
|
||||
using std::list;
|
||||
for (list<AssEntry*>::iterator cur=Line.begin();cur!=Line.end();cur++) {
|
||||
AssDialogue *current = AssEntry::GetAsDialogue(*cur);
|
||||
if (current) {
|
||||
// Get line
|
||||
if (current->Comment) throw _T("Unexpected line type (comment)");
|
||||
|
||||
// Write line
|
||||
file.WriteLineToFile(wxString::Format(_T("%i"),i));
|
||||
file.WriteLineToFile(current->Start.GetSRTFormated() + _T(" --> ") + current->End.GetSRTFormated());
|
||||
file.WriteLineToFile(current->Text);
|
||||
file.WriteLineToFile(_T(""));
|
||||
|
||||
i++;
|
||||
}
|
||||
else throw _T("Unexpected line type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Convert line to SRT
|
||||
void AssFile::DialogueToSRT(AssDialogue *current,std::list<AssEntry*>::iterator prev) {
|
||||
using std::list;
|
||||
AssDialogue *previous;
|
||||
if (prev != Line.end()) previous = AssEntry::GetAsDialogue(*prev);
|
||||
else previous = NULL;
|
||||
|
||||
// Strip ASS tags
|
||||
current->ConvertTagsToSRT();
|
||||
|
||||
// Join equal lines
|
||||
if (previous != NULL) {
|
||||
if (previous->Text == current->Text) {
|
||||
if (abs(current->Start.GetMS() - previous->End.GetMS()) < 20) {
|
||||
current->Start = (current->Start < previous->Start ? current->Start : previous->Start);
|
||||
current->End = (current->End > previous->End ? current->End : previous->End);
|
||||
delete *prev;
|
||||
Line.erase(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix line breaks
|
||||
size_t cur = 0;
|
||||
while ((cur = current->Text.find(_T("\\n"),cur)) != wxString::npos) {
|
||||
current->Text.replace(cur,2,_T("\r\n"));
|
||||
}
|
||||
cur = 0;
|
||||
while ((cur = current->Text.find(_T("\\N"),cur)) != wxString::npos) {
|
||||
current->Text.replace(cur,2,_T("\r\n"));
|
||||
}
|
||||
cur = 0;
|
||||
while ((cur = current->Text.find(_T("\r\n\r\n"),cur)) != wxString::npos) {
|
||||
current->Text.replace(cur,2,_T("\r\n"));
|
||||
cur = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Converts whole file to SRT
|
||||
void AssFile::ConvertToSRT () {
|
||||
using std::list;
|
||||
list<AssEntry*>::iterator next;
|
||||
list<AssEntry*>::iterator prev = Line.end();
|
||||
|
||||
// Sort lines
|
||||
Line.sort(LessByPointedToValue<AssEntry>());
|
||||
|
||||
// Process lines
|
||||
bool notfirst = false;
|
||||
for (list<AssEntry*>::iterator cur=Line.begin();cur!=Line.end();cur=next) {
|
||||
next = cur;
|
||||
next++;
|
||||
|
||||
// Dialogue line (not comment)
|
||||
AssDialogue *current = AssEntry::GetAsDialogue(*cur);
|
||||
if (current && !current->Comment) {
|
||||
DialogueToSRT(current,prev);
|
||||
notfirst = true;
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
// Other line, delete it
|
||||
else {
|
||||
delete *cur;
|
||||
Line.erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Appends line to Ass
|
||||
int AssFile::AddLine (wxString data,wxString group,int lasttime,bool &IsSSA) {
|
||||
|
|
|
@ -67,18 +67,6 @@ private:
|
|||
static bool StackModified;
|
||||
static void StackClear();
|
||||
|
||||
// I/O operations
|
||||
void SaveASS(const wxString file,const wxString encoding=_T(""));
|
||||
void SaveSSA(const wxString file,const wxString encoding=_T(""));
|
||||
void SaveSRT(const wxString file,const wxString encoding=_T(""));
|
||||
|
||||
// Manipulation operations
|
||||
void ConvertToSRT();
|
||||
void DialogueToSRT(AssDialogue *current,std::list<AssEntry*>::iterator prev);
|
||||
|
||||
// Format conversion operations
|
||||
void ConvertToSSA();
|
||||
|
||||
public:
|
||||
std::list<AssEntry*> Line;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
///////////
|
||||
// Headers
|
||||
#include "subtitle_format_reader.h"
|
||||
#include "subtitle_format.h"
|
||||
#include "subtitle_format_ass.h"
|
||||
#include "subtitle_format_srt.h"
|
||||
#include "subtitle_format_txt.h"
|
||||
|
@ -45,41 +45,113 @@
|
|||
|
||||
///////////////
|
||||
// Constructor
|
||||
SubtitleFormatReader::SubtitleFormatReader() {
|
||||
SubtitleFormat::SubtitleFormat() {
|
||||
Line = NULL;
|
||||
Register();
|
||||
isCopy = false;
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Destructor
|
||||
SubtitleFormatReader::~SubtitleFormatReader() {
|
||||
SubtitleFormat::~SubtitleFormat () {
|
||||
Remove();
|
||||
}
|
||||
|
||||
|
||||
////////
|
||||
// List
|
||||
std::list<SubtitleFormat*> SubtitleFormat::formats;
|
||||
bool SubtitleFormat::loaded = false;
|
||||
|
||||
|
||||
//////////////
|
||||
// Set target
|
||||
void SubtitleFormatReader::SetTarget(AssFile *file) {
|
||||
void SubtitleFormat::SetTarget(AssFile *file) {
|
||||
ClearCopy();
|
||||
if (!file) Line = NULL;
|
||||
else Line = &file->Line;
|
||||
assFile = file;
|
||||
}
|
||||
|
||||
|
||||
////////
|
||||
// List
|
||||
std::list<SubtitleFormatReader*> SubtitleFormatReader::readers;
|
||||
bool SubtitleFormatReader::loaded = false;
|
||||
///////////////
|
||||
// Create copy
|
||||
void SubtitleFormat::CreateCopy() {
|
||||
SetTarget(new AssFile(*assFile));
|
||||
isCopy = true;
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Clear copy
|
||||
void SubtitleFormat::ClearCopy() {
|
||||
if (isCopy) {
|
||||
delete assFile;
|
||||
assFile = NULL;
|
||||
isCopy = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Clear subtitles
|
||||
void SubtitleFormat::Clear() {
|
||||
assFile->Clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// Load default
|
||||
void SubtitleFormat::LoadDefault() {
|
||||
assFile->LoadDefault();
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Set if it's ASS
|
||||
void SubtitleFormat::SetIsASS(bool isASS) {
|
||||
assFile->IsASS = isASS;
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
// Add line
|
||||
int SubtitleFormat::AddLine(wxString data,wxString group,int lasttime,bool &IsSSA) {
|
||||
return assFile->AddLine(data,group,lasttime,IsSSA);
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// Add formats
|
||||
void SubtitleFormat::LoadFormats () {
|
||||
if (!loaded) {
|
||||
new ASSSubtitleFormat();
|
||||
new SRTSubtitleFormat();
|
||||
new TXTSubtitleFormat();
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Destroy formats
|
||||
void SubtitleFormat::DestroyFormats () {
|
||||
std::list<SubtitleFormat*>::iterator cur;
|
||||
for (cur=formats.begin();cur!=formats.end();cur = formats.begin()) {
|
||||
delete *cur;
|
||||
}
|
||||
formats.clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Get an appropriate reader
|
||||
SubtitleFormatReader *SubtitleFormatReader::GetReader(wxString filename) {
|
||||
LoadReaders();
|
||||
std::list<SubtitleFormatReader*>::iterator cur;
|
||||
SubtitleFormatReader *reader;
|
||||
for (cur=readers.begin();cur!=readers.end();cur++) {
|
||||
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;
|
||||
}
|
||||
|
@ -87,81 +159,39 @@ SubtitleFormatReader *SubtitleFormatReader::GetReader(wxString filename) {
|
|||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Get an appropriate writer
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
// Register
|
||||
void SubtitleFormatReader::Register() {
|
||||
std::list<SubtitleFormatReader*>::iterator cur;
|
||||
for (cur=readers.begin();cur!=readers.end();cur++) {
|
||||
void SubtitleFormat::Register() {
|
||||
std::list<SubtitleFormat*>::iterator cur;
|
||||
for (cur=formats.begin();cur!=formats.end();cur++) {
|
||||
if (*cur == this) return;
|
||||
}
|
||||
readers.push_back(this);
|
||||
formats.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Remove
|
||||
void SubtitleFormatReader::Remove() {
|
||||
std::list<SubtitleFormatReader*>::iterator cur;
|
||||
for (cur=readers.begin();cur!=readers.end();cur++) {
|
||||
void SubtitleFormat::Remove() {
|
||||
std::list<SubtitleFormat*>::iterator cur;
|
||||
for (cur=formats.begin();cur!=formats.end();cur++) {
|
||||
if (*cur == this) {
|
||||
readers.erase(cur);
|
||||
formats.erase(cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Clear subtitles
|
||||
void SubtitleFormatReader::Clear() {
|
||||
assFile->Clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// Load default
|
||||
void SubtitleFormatReader::LoadDefault() {
|
||||
assFile->LoadDefault();
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Set if it's ASS
|
||||
void SubtitleFormatReader::SetIsASS(bool isASS) {
|
||||
assFile->IsASS = isASS;
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
// Add line
|
||||
int SubtitleFormatReader::AddLine(wxString data,wxString group,int lasttime,bool &IsSSA) {
|
||||
return assFile->AddLine(data,group,lasttime,IsSSA);
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// Add loaders
|
||||
void SubtitleFormatReader::LoadReaders () {
|
||||
if (!loaded) {
|
||||
new ASSSubtitleFormatReader();
|
||||
new SRTSubtitleFormatReader();
|
||||
new TXTSubtitleFormatReader();
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Destroy loaders
|
||||
void SubtitleFormatReader::DestroyReaders () {
|
||||
SubtitleFormatReader *reader;
|
||||
std::list<SubtitleFormatReader*>::iterator cur,next;
|
||||
for (cur=readers.begin();cur!=readers.end();cur = next) {
|
||||
next = cur;
|
||||
next++;
|
||||
reader = *cur;
|
||||
readers.erase(cur);
|
||||
delete reader;
|
||||
}
|
||||
readers.clear();
|
||||
}
|
|
@ -51,31 +51,39 @@ class AssEntry;
|
|||
|
||||
///////////////////
|
||||
// Subtitle reader
|
||||
class SubtitleFormatReader {
|
||||
class SubtitleFormat {
|
||||
private:
|
||||
bool isCopy;
|
||||
AssFile *assFile;
|
||||
|
||||
void Register();
|
||||
void Remove();
|
||||
static std::list<SubtitleFormatReader*> readers;
|
||||
|
||||
static std::list<SubtitleFormat*> formats;
|
||||
static bool loaded;
|
||||
AssFile *assFile;
|
||||
|
||||
protected:
|
||||
std::list<AssEntry*> *Line;
|
||||
void CreateCopy();
|
||||
void ClearCopy();
|
||||
|
||||
public:
|
||||
SubtitleFormatReader();
|
||||
virtual ~SubtitleFormatReader();
|
||||
|
||||
virtual bool CanReadFile(wxString filename)=0;
|
||||
virtual void ReadFile(wxString filename,wxString forceEncoding=_T(""))=0;
|
||||
|
||||
void SetTarget(AssFile *file);
|
||||
void Clear();
|
||||
void LoadDefault();
|
||||
void SetIsASS(bool isASS);
|
||||
int AddLine(wxString data,wxString group,int lasttime,bool &IsSSA);
|
||||
|
||||
static SubtitleFormatReader *GetReader(wxString filename);
|
||||
static void LoadReaders();
|
||||
static void DestroyReaders();
|
||||
public:
|
||||
SubtitleFormat();
|
||||
virtual ~SubtitleFormat();
|
||||
void SetTarget(AssFile *file);
|
||||
|
||||
virtual bool CanReadFile(wxString filename) { return false; };
|
||||
virtual bool CanWriteFile(wxString filename) { return false; };
|
||||
virtual void ReadFile(wxString filename,wxString forceEncoding=_T("")) { };
|
||||
virtual void WriteFile(wxString filename,wxString encoding=_T("")) { };
|
||||
|
||||
static SubtitleFormat *GetReader(wxString filename);
|
||||
static SubtitleFormat *GetWriter(wxString filename);
|
||||
static void LoadFormats();
|
||||
static void DestroyFormats();
|
||||
};
|
|
@ -38,19 +38,20 @@
|
|||
// Headers
|
||||
#include "subtitle_format_ass.h"
|
||||
#include "text_file_reader.h"
|
||||
#include "text_file_writer.h"
|
||||
#include "ass_dialogue.h"
|
||||
|
||||
|
||||
/////////////
|
||||
// Can read?
|
||||
bool ASSSubtitleFormatReader::CanReadFile(wxString filename) {
|
||||
bool ASSSubtitleFormat::CanReadFile(wxString filename) {
|
||||
return (filename.Right(4).Lower() == _T(".ass") || filename.Right(4).Lower() == _T(".ssa"));
|
||||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Read file
|
||||
void ASSSubtitleFormatReader::ReadFile(wxString filename,wxString encoding) {
|
||||
void ASSSubtitleFormat::ReadFile(wxString filename,wxString encoding) {
|
||||
using namespace std;
|
||||
|
||||
// Reader
|
||||
|
@ -91,3 +92,26 @@ void ASSSubtitleFormatReader::ReadFile(wxString filename,wxString encoding) {
|
|||
// Set ASS
|
||||
SetIsASS(!IsSSA);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Can write to file?
|
||||
bool ASSSubtitleFormat::CanWriteFile(wxString filename) {
|
||||
return (filename.Right(4).Lower() == _T(".ass") || filename.Right(4).Lower() == _T(".ssa"));
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Write file
|
||||
void ASSSubtitleFormat::WriteFile(wxString _filename,wxString encoding) {
|
||||
// Open file
|
||||
TextFileWriter file(_filename,encoding);
|
||||
bool ssa = _filename.Right(4).Lower() == _T(".ssa");
|
||||
|
||||
// Write lines
|
||||
using std::list;
|
||||
for (list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
|
||||
if (ssa) file.WriteLineToFile((*cur)->GetSSAText());
|
||||
else file.WriteLineToFile((*cur)->GetEntryData());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
///////////
|
||||
// Headers
|
||||
#include "subtitle_format_reader.h"
|
||||
#include "subtitle_format.h"
|
||||
|
||||
|
||||
//////////////
|
||||
|
@ -47,12 +47,13 @@
|
|||
class AssDialogue;
|
||||
|
||||
|
||||
//////////////
|
||||
// SRT reader
|
||||
class ASSSubtitleFormatReader : public SubtitleFormatReader {
|
||||
private:
|
||||
|
||||
/////////////////////
|
||||
// ASS reader/writer
|
||||
class ASSSubtitleFormat : public SubtitleFormat {
|
||||
public:
|
||||
bool CanReadFile(wxString filename);
|
||||
void ReadFile(wxString filename,wxString forceEncoding);
|
||||
|
||||
bool CanWriteFile(wxString filename);
|
||||
void WriteFile(wxString filename,wxString encoding);
|
||||
};
|
||||
|
|
|
@ -38,19 +38,21 @@
|
|||
// Headers
|
||||
#include "subtitle_format_srt.h"
|
||||
#include "text_file_reader.h"
|
||||
#include "text_file_writer.h"
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_file.h"
|
||||
|
||||
|
||||
/////////////
|
||||
// Can read?
|
||||
bool SRTSubtitleFormatReader::CanReadFile(wxString filename) {
|
||||
bool SRTSubtitleFormat::CanReadFile(wxString filename) {
|
||||
return (filename.Right(4).Lower() == _T(".srt"));
|
||||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Read file
|
||||
void SRTSubtitleFormatReader::ReadFile(wxString filename,wxString encoding) {
|
||||
void SRTSubtitleFormat::ReadFile(wxString filename,wxString encoding) {
|
||||
using namespace std;
|
||||
|
||||
// Reader
|
||||
|
@ -122,3 +124,115 @@ void SRTSubtitleFormatReader::ReadFile(wxString filename,wxString encoding) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Can write?
|
||||
bool SRTSubtitleFormat::CanWriteFile(wxString filename) {
|
||||
return (filename.Right(4).Lower() == _T(".srt"));
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Write file
|
||||
void SRTSubtitleFormat::WriteFile(wxString _filename,wxString encoding) {
|
||||
// Open file
|
||||
TextFileWriter file(_filename,encoding);
|
||||
|
||||
// Convert to SRT
|
||||
CreateCopy();
|
||||
ConvertToSRT();
|
||||
|
||||
// Write lines
|
||||
int i=1;
|
||||
using std::list;
|
||||
for (list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur++) {
|
||||
AssDialogue *current = AssEntry::GetAsDialogue(*cur);
|
||||
if (current) {
|
||||
// Get line
|
||||
if (current->Comment) throw _T("Unexpected line type (comment)");
|
||||
|
||||
// Write line
|
||||
file.WriteLineToFile(wxString::Format(_T("%i"),i));
|
||||
file.WriteLineToFile(current->Start.GetSRTFormated() + _T(" --> ") + current->End.GetSRTFormated());
|
||||
file.WriteLineToFile(current->Text);
|
||||
file.WriteLineToFile(_T(""));
|
||||
|
||||
i++;
|
||||
}
|
||||
else throw _T("Unexpected line type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Convert line to SRT
|
||||
void SRTSubtitleFormat::DialogueToSRT(AssDialogue *current,std::list<AssEntry*>::iterator prev) {
|
||||
using std::list;
|
||||
AssDialogue *previous;
|
||||
if (prev != Line->end()) previous = AssEntry::GetAsDialogue(*prev);
|
||||
else previous = NULL;
|
||||
|
||||
// Strip ASS tags
|
||||
current->ConvertTagsToSRT();
|
||||
|
||||
// Join equal lines
|
||||
if (previous != NULL) {
|
||||
if (previous->Text == current->Text) {
|
||||
if (abs(current->Start.GetMS() - previous->End.GetMS()) < 20) {
|
||||
current->Start = (current->Start < previous->Start ? current->Start : previous->Start);
|
||||
current->End = (current->End > previous->End ? current->End : previous->End);
|
||||
delete *prev;
|
||||
Line->erase(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix line breaks
|
||||
size_t cur = 0;
|
||||
while ((cur = current->Text.find(_T("\\n"),cur)) != wxString::npos) {
|
||||
current->Text.replace(cur,2,_T("\r\n"));
|
||||
}
|
||||
cur = 0;
|
||||
while ((cur = current->Text.find(_T("\\N"),cur)) != wxString::npos) {
|
||||
current->Text.replace(cur,2,_T("\r\n"));
|
||||
}
|
||||
cur = 0;
|
||||
while ((cur = current->Text.find(_T("\r\n\r\n"),cur)) != wxString::npos) {
|
||||
current->Text.replace(cur,2,_T("\r\n"));
|
||||
cur = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Converts whole file to SRT
|
||||
void SRTSubtitleFormat::ConvertToSRT () {
|
||||
using std::list;
|
||||
list<AssEntry*>::iterator next;
|
||||
list<AssEntry*>::iterator prev = Line->end();
|
||||
|
||||
// Sort lines
|
||||
Line->sort(LessByPointedToValue<AssEntry>());
|
||||
|
||||
// Process lines
|
||||
bool notfirst = false;
|
||||
for (list<AssEntry*>::iterator cur=Line->begin();cur!=Line->end();cur=next) {
|
||||
next = cur;
|
||||
next++;
|
||||
|
||||
// Dialogue line (not comment)
|
||||
AssDialogue *current = AssEntry::GetAsDialogue(*cur);
|
||||
if (current && !current->Comment) {
|
||||
DialogueToSRT(current,prev);
|
||||
notfirst = true;
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
// Other line, delete it
|
||||
else {
|
||||
delete *cur;
|
||||
Line->erase(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
///////////
|
||||
// Headers
|
||||
#include "subtitle_format_reader.h"
|
||||
#include "subtitle_format.h"
|
||||
|
||||
|
||||
//////////////
|
||||
|
@ -47,12 +47,17 @@
|
|||
class AssDialogue;
|
||||
|
||||
|
||||
//////////////
|
||||
// SRT reader
|
||||
class SRTSubtitleFormatReader : public SubtitleFormatReader {
|
||||
/////////////////////
|
||||
// SRT reader/writer
|
||||
class SRTSubtitleFormat : public SubtitleFormat {
|
||||
private:
|
||||
void ConvertToSRT();
|
||||
void DialogueToSRT(AssDialogue *current,std::list<AssEntry*>::iterator prev);
|
||||
|
||||
public:
|
||||
bool CanReadFile(wxString filename);
|
||||
void ReadFile(wxString filename,wxString forceEncoding);
|
||||
|
||||
bool CanWriteFile(wxString filename);
|
||||
void WriteFile(wxString filename,wxString encoding);
|
||||
};
|
||||
|
|
|
@ -44,14 +44,14 @@
|
|||
|
||||
/////////////
|
||||
// Can read?
|
||||
bool TXTSubtitleFormatReader::CanReadFile(wxString filename) {
|
||||
bool TXTSubtitleFormat::CanReadFile(wxString filename) {
|
||||
return (filename.Right(4).Lower() == _T(".txt"));
|
||||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Read file
|
||||
void TXTSubtitleFormatReader::ReadFile(wxString filename,wxString encoding) { using namespace std;
|
||||
void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) { using namespace std;
|
||||
|
||||
// Reader
|
||||
TextFileReader file(filename,encoding,false);
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
///////////
|
||||
// Headers
|
||||
#include "subtitle_format_reader.h"
|
||||
#include "subtitle_format.h"
|
||||
|
||||
|
||||
//////////////
|
||||
|
@ -49,7 +49,7 @@ class AssDialogue;
|
|||
|
||||
//////////////
|
||||
// TXT reader
|
||||
class TXTSubtitleFormatReader : public SubtitleFormatReader {
|
||||
class TXTSubtitleFormat : public SubtitleFormat {
|
||||
private:
|
||||
|
||||
public:
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
// Copyright (c) 2006, Rodrigo Braz Monteiro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "subtitle_format_writer.h"
|
||||
#include "subtitle_format_ass.h"
|
||||
#include "subtitle_format_srt.h"
|
||||
#include "subtitle_format_txt.h"
|
||||
#include "ass_file.h"
|
||||
|
||||
|
||||
///////////////
|
||||
// Constructor
|
||||
SubtitleFormatWriter::SubtitleFormatWriter() {
|
||||
Line = NULL;
|
||||
Register();
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Destructor
|
||||
SubtitleFormatWriter::~SubtitleFormatWriter() {
|
||||
Remove();
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Set target
|
||||
void SubtitleFormatWriter::SetTarget(AssFile *file) {
|
||||
if (!file) Line = NULL;
|
||||
else Line = &file->Line;
|
||||
assFile = file;
|
||||
}
|
||||
|
||||
|
||||
////////
|
||||
// List
|
||||
std::list<SubtitleFormatWriter*> SubtitleFormatWriter::writers;
|
||||
bool SubtitleFormatWriter::loaded = false;
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// Get an appropriate writer
|
||||
SubtitleFormatWriter *SubtitleFormatWriter::GetWriter(wxString filename) {
|
||||
LoadWriters();
|
||||
std::list<SubtitleFormatWriter*>::iterator cur;
|
||||
SubtitleFormatWriter *writer;
|
||||
for (cur=writers.begin();cur!=writers.end();cur++) {
|
||||
writer = *cur;
|
||||
if (writer->CanWriteFile(filename)) return writer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
// Register
|
||||
void SubtitleFormatWriter::Register() {
|
||||
std::list<SubtitleFormatWriter*>::iterator cur;
|
||||
for (cur=writers.begin();cur!=writers.end();cur++) {
|
||||
if (*cur == this) return;
|
||||
}
|
||||
writers.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Remove
|
||||
void SubtitleFormatWriter::Remove() {
|
||||
std::list<SubtitleFormatWriter*>::iterator cur;
|
||||
for (cur=writers.begin();cur!=writers.end();cur++) {
|
||||
if (*cur == this) {
|
||||
writers.erase(cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// Add loaders
|
||||
void SubtitleFormatWriter::LoadWriters () {
|
||||
if (!loaded) {
|
||||
//new ASSSubtitleFormatWriter();
|
||||
//new SRTSubtitleFormatWriter();
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Destroy loaders
|
||||
void SubtitleFormatWriter::DestroyWriters () {
|
||||
SubtitleFormatWriter *writer;
|
||||
std::list<SubtitleFormatWriter*>::iterator cur,next;
|
||||
for (cur=writers.begin();cur!=writers.end();cur = next) {
|
||||
next = cur;
|
||||
next++;
|
||||
writer = *cur;
|
||||
writers.erase(cur);
|
||||
delete writer;
|
||||
}
|
||||
writers.clear();
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (c) 2006, Rodrigo Braz Monteiro
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// AEGISUB
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include <wx/wxprec.h>
|
||||
#include <list>
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class AssFile;
|
||||
class AssEntry;
|
||||
|
||||
|
||||
///////////////////
|
||||
// Subtitle reader
|
||||
class SubtitleFormatWriter {
|
||||
private:
|
||||
void Register();
|
||||
void Remove();
|
||||
static std::list<SubtitleFormatWriter*> writers;
|
||||
static bool loaded;
|
||||
AssFile *assFile;
|
||||
|
||||
protected:
|
||||
std::list<AssEntry*> *Line;
|
||||
|
||||
public:
|
||||
SubtitleFormatWriter();
|
||||
virtual ~SubtitleFormatWriter();
|
||||
|
||||
virtual bool CanWriteFile(wxString filename)=0;
|
||||
virtual void WriteFile(wxString filename,wxString encoding)=0;
|
||||
|
||||
void SetTarget(AssFile *file);
|
||||
|
||||
static SubtitleFormatWriter *GetWriter(wxString filename);
|
||||
static void LoadWriters();
|
||||
static void DestroyWriters();
|
||||
};
|
Loading…
Reference in New Issue