New subtitle load system implemented

Originally committed to SVN as r181.
This commit is contained in:
Rodrigo Braz Monteiro 2006-02-27 00:06:46 +00:00
parent 20c783f83d
commit 39225db7c8
8 changed files with 387 additions and 158 deletions

View File

@ -48,7 +48,7 @@
#include "text_file_reader.h"
#include "text_file_writer.h"
#include "version.h"
#include "subtitle_format_srt.h"
#include "subtitle_format_reader.h"
////////////////////// AssFile //////////////////////
@ -87,47 +87,21 @@ void AssFile::Load (const wxString _filename,const wxString charset) {
else enc = charset;
TextFileReader::EnsureValid(enc);
// Get extension
int i = 0;
for (i=(int)_filename.size();--i>=0;) {
if (_filename[i] == _T('.')) break;
}
wxString extension = _filename.substr(i+1);
extension.Lower();
// Generic preparation
Clear();
IsASS = false;
// ASS
if (extension == _T("ass")) {
LoadASS(_filename,enc,false);
}
// SRT
else if (extension == _T("srt")) {
//LoadSRT(_filename,enc);
SRTSubtitleFormatReader srt;
srt.SetTarget(this);
srt.ReadFile(_filename,enc);
}
// Get proper format reader
SubtitleFormatReader *reader = SubtitleFormatReader::GetReader(_filename);
// SSA
else if (extension == _T("ssa")) {
LoadASS(_filename,enc,true);
}
// TXT
else if (extension == _T("txt")) {
LoadTXT(_filename,enc);
// Read file
if (reader) {
reader->SetTarget(this);
reader->ReadFile(_filename,enc);
}
// Couldn't find a type
else {
wxString error = _T("Unknown file type: ");
error += extension;
throw error;
}
else throw _T("Unknown file type.");
}
// String error
@ -162,127 +136,6 @@ void AssFile::Load (const wxString _filename,const wxString charset) {
}
///////////////////////////
// Load Ass file from disk
void AssFile::LoadASS (const wxString _filename,const wxString encoding,bool IsSSA) {
using namespace std;
// Reader
TextFileReader file(_filename,encoding);
// Parse file
wxString curgroup;
int lasttime = -1;
while (file.HasMoreLines()) {
// Reads line
wxString wxbuffer = file.ReadLineFromFile();
// Convert v4 styles to v4+ styles
if (wxbuffer.Lower() == _T("[v4 styles]")) {
wxbuffer = _T("[V4+ Styles]");
}
// Set group
if (wxbuffer[0] == _T('[')) {
curgroup = wxbuffer;
}
// Add line
try {
lasttime = AddLine(wxbuffer,curgroup,lasttime,IsSSA);
}
catch (wchar_t *err) {
Clear();
throw wxString(_T("Error processing line: ")) + wxbuffer + _T(": ") + wxString(err);
}
catch (...) {
Clear();
throw wxString(_T("Error processing line: ")) + wxbuffer;
}
}
// Set ASS
IsASS = !IsSSA;
}
////////////////////////////
// Loads TXT subs from disk
void AssFile::LoadTXT (wxString _filename,wxString encoding) {
using namespace std;
// Reader
TextFileReader file(_filename,encoding,false);
// Default
LoadDefault(false);
IsASS = false;
// Data
wxString actor;
wxString separator = Options.AsText(_T("Text actor separator"));
wxString comment = Options.AsText(_T("Text comment starter"));
bool isComment = false;
// Parse file
AssDialogue *line = NULL;
while (file.HasMoreLines()) {
// Reads line
wxString value = file.ReadLineFromFile();
// Check if this isn't a timecodes file
if (value.Left(10) == _T("# timecode")) {
throw _T("File is a timecode file, cannot load as subtitles.");
}
// Read comment data
isComment = false;
if (comment != _T("") && value.Left(comment.Length()) == comment) {
isComment = true;
value = value.Mid(comment.Length());
}
// Read actor data
if (!isComment && separator != _T("")) {
if (value[0] != _T(' ') && value[0] != _T('\t')) {
size_t pos = value.Find(separator);
if (pos != -1) {
actor = value.Left(pos);
actor.Trim(false);
actor.Trim(true);
value = value.Mid(pos+1);
value.Trim(false);
}
}
}
// Trim spaces at start
value.Trim(false);
// Sets line up
line = new AssDialogue();
line->group = _T("[Events]");
line->Style = _T("Default");
if (isComment) line->Actor = _T("");
else line->Actor = actor;
if (value.IsEmpty()) {
line->Actor = _T("");
isComment = true;
}
line->Comment = isComment;
line->Text = value;
line->StartMS = 0;
line->Start.SetMS(0);
line->End.SetMS(0);
line->UpdateData();
//line->ParseASSTags();
// Adds line
Line.push_back(line);
}
}
/////////////////////////////
// Chooses format to save in
void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wxString encoding) {

View File

@ -68,14 +68,11 @@ private:
static void StackClear();
// I/O operations
void LoadASS(const wxString file,const wxString encoding,bool IsSSA=false);
void LoadTXT(const wxString file,const wxString encoding);
void SaveASS(const wxString file,bool setfilename,const wxString encoding=_T(""));
void SaveSSA(const wxString file,const wxString encoding=_T(""));
void SaveSRT(const wxString file,const wxString encoding=_T(""));
// Manipulation operations
int AddLine(wxString data,wxString group,int lasttime,bool &IsSSA);
void ConvertToSRT();
void DialogueToSRT(AssDialogue *current,std::list<AssEntry*>::iterator prev);
@ -111,6 +108,7 @@ public:
wxString GetScriptInfo(const wxString key); // Returns the value in a [Script Info] key.
void SetScriptInfo(const wxString key,const wxString value); // Sets the value of a [Script Info] key. Adds it if it doesn't exist.
void AddComment(const wxString comment); // Adds a ";" comment under [Script Info].
int AddLine(wxString data,wxString group,int lasttime,bool &IsSSA);
static void StackPop(); // Pop subs from stack and sets 'top' to it
static void StackRedo(); // Redoes action on stack

View File

@ -0,0 +1,93 @@
// 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_ass.h"
#include "text_file_reader.h"
#include "ass_dialogue.h"
/////////////
// Can read?
bool ASSSubtitleFormatReader::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) {
using namespace std;
// Reader
TextFileReader file(filename,encoding);
bool IsSSA = filename.Right(4).Lower() == _T(".ssa");
// Parse file
wxString curgroup;
int lasttime = -1;
while (file.HasMoreLines()) {
// Reads line
wxString wxbuffer = file.ReadLineFromFile();
// Convert v4 styles to v4+ styles
if (wxbuffer.Lower() == _T("[v4 styles]")) {
wxbuffer = _T("[V4+ Styles]");
}
// Set group
if (wxbuffer[0] == _T('[')) {
curgroup = wxbuffer;
}
// Add line
try {
lasttime = AddLine(wxbuffer,curgroup,lasttime,IsSSA);
}
catch (wchar_t *err) {
Clear();
throw wxString(_T("Error processing line: ")) + wxbuffer + _T(": ") + wxString(err);
}
catch (...) {
Clear();
throw wxString(_T("Error processing line: ")) + wxbuffer;
}
}
// Set ASS
SetIsASS(!IsSSA);
}

View File

@ -0,0 +1,58 @@
// 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 "subtitle_format_reader.h"
//////////////
// Prototypes
class AssDialogue;
//////////////
// SRT reader
class ASSSubtitleFormatReader : public SubtitleFormatReader {
private:
public:
bool CanReadFile(wxString filename);
void ReadFile(wxString filename,wxString forceEncoding);
};

View File

@ -37,6 +37,9 @@
///////////
// Headers
#include "subtitle_format_reader.h"
#include "subtitle_format_ass.h"
#include "subtitle_format_srt.h"
#include "subtitle_format_txt.h"
#include "ass_file.h"
@ -67,11 +70,13 @@ void SubtitleFormatReader::SetTarget(AssFile *file) {
////////
// List
std::list<SubtitleFormatReader*> SubtitleFormatReader::readers;
bool SubtitleFormatReader::loaded = false;
/////////////////////////////
// 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++) {
@ -125,3 +130,38 @@ void SubtitleFormatReader::LoadDefault() {
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();
}

View File

@ -56,6 +56,7 @@ private:
void Register();
void Remove();
static std::list<SubtitleFormatReader*> readers;
static bool loaded;
AssFile *assFile;
protected:
@ -72,6 +73,9 @@ public:
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();
};

View File

@ -0,0 +1,125 @@
// 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_txt.h"
#include "text_file_reader.h"
#include "ass_dialogue.h"
#include "options.h"
/////////////
// Can read?
bool TXTSubtitleFormatReader::CanReadFile(wxString filename) {
return (filename.Right(4).Lower() == _T(".txt"));
}
/////////////
// Read file
void TXTSubtitleFormatReader::ReadFile(wxString filename,wxString encoding) { using namespace std;
// Reader
TextFileReader file(filename,encoding,false);
// Default
LoadDefault();
SetIsASS(false);
// Data
wxString actor;
wxString separator = Options.AsText(_T("Text actor separator"));
wxString comment = Options.AsText(_T("Text comment starter"));
bool isComment = false;
// Parse file
AssDialogue *line = NULL;
while (file.HasMoreLines()) {
// Reads line
wxString value = file.ReadLineFromFile();
// Check if this isn't a timecodes file
if (value.Left(10) == _T("# timecode")) {
throw _T("File is a timecode file, cannot load as subtitles.");
}
// Read comment data
isComment = false;
if (comment != _T("") && value.Left(comment.Length()) == comment) {
isComment = true;
value = value.Mid(comment.Length());
}
// Read actor data
if (!isComment && separator != _T("")) {
if (value[0] != _T(' ') && value[0] != _T('\t')) {
size_t pos = value.Find(separator);
if (pos != -1) {
actor = value.Left(pos);
actor.Trim(false);
actor.Trim(true);
value = value.Mid(pos+1);
value.Trim(false);
}
}
}
// Trim spaces at start
value.Trim(false);
// Sets line up
line = new AssDialogue();
line->group = _T("[Events]");
line->Style = _T("Default");
if (isComment) line->Actor = _T("");
else line->Actor = actor;
if (value.IsEmpty()) {
line->Actor = _T("");
isComment = true;
}
line->Comment = isComment;
line->Text = value;
line->StartMS = 0;
line->Start.SetMS(0);
line->End.SetMS(0);
line->UpdateData();
//line->ParseASSTags();
// Adds line
Line->push_back(line);
}
}

View File

@ -0,0 +1,58 @@
// 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 "subtitle_format_reader.h"
//////////////
// Prototypes
class AssDialogue;
//////////////
// TXT reader
class TXTSubtitleFormatReader : public SubtitleFormatReader {
private:
public:
bool CanReadFile(wxString filename);
void ReadFile(wxString filename,wxString forceEncoding);
};