Completely broken TTXT writing pseudo-implemented.

Originally committed to SVN as r1255.
This commit is contained in:
Rodrigo Braz Monteiro 2007-06-18 22:20:50 +00:00
parent 808a1fe06c
commit 14195cc2bb
4 changed files with 230 additions and 66 deletions

View file

@ -131,12 +131,12 @@ void AssTime::SetMS (int _ms) {
//////////////// ////////////////
// ASS Formated // ASS Formated
wxString AssTime::GetASSFormated () { wxString AssTime::GetASSFormated (bool msPrecision) {
int h,m,s,ms; int h,m,s,ms;
int _ms = time; int _ms = time;
// Centisecond precision // Centisecond precision
if (!UseMSPrecision) _ms = _ms/10*10; if (!UseMSPrecision && !msPrecision) _ms = _ms/10*10;
// Reset // Reset
h = m = s = ms = 0; h = m = s = ms = 0;

View file

@ -57,7 +57,7 @@ public:
void SetMS(int ms); // Sets values to miliseconds void SetMS(int ms); // Sets values to miliseconds
void ParseASS(const wxString text); // Sets value to text-form time, in ASS format void ParseASS(const wxString text); // Sets value to text-form time, in ASS format
void ParseSRT(const wxString text); // Sets value to text-form time, in SRT format void ParseSRT(const wxString text); // Sets value to text-form time, in SRT format
wxString GetASSFormated(); // Returns the ASS representation of time wxString GetASSFormated(bool ms=false); // Returns the ASS representation of time
wxString GetSRTFormated(); // Returns the SRT representation of time wxString GetSRTFormated(); // Returns the SRT representation of time
void UpdateFromTextCtrl(wxTextCtrl *ctrl); // Reads value from text control and updates both void UpdateFromTextCtrl(wxTextCtrl *ctrl); // Reads value from text control and updates both
}; };

View file

@ -37,9 +37,8 @@
/////////// ///////////
// Headers // Headers
#include "subtitle_format_ttxt.h" #include "subtitle_format_ttxt.h"
#include "ass_dialogue.h"
#include "ass_time.h" #include "ass_time.h"
#include <wx/xml/xml.h> #include "ass_file.h"
/////////////////// ///////////////////
@ -61,8 +60,8 @@ wxArrayString TTXTSubtitleFormat::GetReadWildcards() {
/////////////////////// ///////////////////////
// Get write wildcards // Get write wildcards
wxArrayString TTXTSubtitleFormat::GetWriteWildcards() { wxArrayString TTXTSubtitleFormat::GetWriteWildcards() {
//return GetReadWildcards(); return GetReadWildcards();
return wxArrayString(); //return wxArrayString();
} }
@ -76,8 +75,8 @@ bool TTXTSubtitleFormat::CanReadFile(wxString filename) {
///////////////////// /////////////////////
// Can write a file? // Can write a file?
bool TTXTSubtitleFormat::CanWriteFile(wxString filename) { bool TTXTSubtitleFormat::CanWriteFile(wxString filename) {
return false; //return false;
//return (filename.Right(5).Lower() == _T(".ttxt")); return (filename.Right(5).Lower() == _T(".ttxt"));
} }
@ -96,23 +95,51 @@ void TTXTSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) {
// Check version // Check version
wxString verStr = doc.GetRoot()->GetPropVal(_T("version"),_T("")); wxString verStr = doc.GetRoot()->GetPropVal(_T("version"),_T(""));
int version = -1; version = -1;
if (verStr == _T("1.0")) version = 0; if (verStr == _T("1.0")) version = 0;
else if (verStr == _T("1.1")) version = 1; else if (verStr == _T("1.1")) version = 1;
else throw wxString(_T("Unknown TTXT version: ") + verStr); else throw wxString(_T("Unknown TTXT version: ") + verStr);
// Get children // Get children
AssDialogue *diag = NULL; diag = NULL;
wxXmlNode *child = doc.GetRoot()->GetChildren(); wxXmlNode *child = doc.GetRoot()->GetChildren();
int lines = 0; int lines = 0;
while (child) { while (child) {
// Line // Line
if (child->GetName() == _T("TextSample")) { if (child->GetName() == _T("TextSample")) {
if (ProcessLine(child)) lines++;
}
// Header
else if (child->GetName() == _T("TextStreamHeader")) {
ProcessHeader(child);
}
// Proceed to next child
child = child->GetNext();
}
// No lines?
if (lines == 0) {
AssDialogue *line = new AssDialogue();
line->group = _T("[Events]");
line->Style = _T("Default");
line->StartMS = 0;
line->Start.SetMS(0);
line->End.SetMS(5000);
Line->push_back(line);
}
}
///////////////////////////
// Process a dialogue line
bool TTXTSubtitleFormat::ProcessLine(wxXmlNode *node) {
// Get properties // Get properties
wxString sampleTime = child->GetPropVal(_T("sampleTime"),_T("00:00:00.000")); wxString sampleTime = node->GetPropVal(_T("sampleTime"),_T("00:00:00.000"));
wxString text; wxString text;
if (version == 0) text = child->GetPropVal(_T("text"),_T("")); if (version == 0) text = node->GetPropVal(_T("text"),_T(""));
else text = child->GetNodeContent(); else text = node->GetNodeContent();
// Parse time // Parse time
AssTime time; AssTime time;
@ -160,33 +187,158 @@ void TTXTSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) {
// Insert dialogue // Insert dialogue
diag->UpdateData(); diag->UpdateData();
Line->push_back(diag); Line->push_back(diag);
lines++; return true;
}
} }
// Header else return false;
else if (child->GetName() == _T("TextStreamHeader")) { }
//////////////////////
// Process the header
void TTXTSubtitleFormat::ProcessHeader(wxXmlNode *node) {
// TODO // TODO
} }
// Proceed to next child
child = child->GetNext();
}
// No lines?
if (lines == 0) {
AssDialogue *line = new AssDialogue();
line->group = _T("[Events]");
line->Style = _T("Default");
line->StartMS = 0;
line->Start.SetMS(0);
line->End.SetMS(5000);
Line->push_back(line);
}
}
//////////////// ////////////////
// Write a file // Write a file
void TTXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) { void TTXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) {
// Convert to TTXT
CreateCopy();
ConvertToTTXT();
// Create XML structure
wxXmlDocument doc;
wxXmlNode *root = new wxXmlNode(NULL,wxXML_ELEMENT_NODE,_T("TextStream"));
root->AddProperty(_T("version"),_T("1.1"));
doc.SetRoot(root);
wxXmlNode *node,*prevNode;
// Create header
node = new wxXmlNode(root,wxXML_ELEMENT_NODE,_T("TextStreamHeader"));
node->AddProperty(_T("width"),_T("400"));
node->AddProperty(_T("height"),_T("60"));
root->AddChild(node);
prevNode = node;
// Create lines
int i=1;
using std::list;
AssDialogue *prev = NULL;
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)");
// If it doesn't start at the end of previous, add blank
if (prev && prev->End != current->Start) {
node = new wxXmlNode(root,wxXML_ELEMENT_NODE,_T("TextSample"));
node->AddProperty(_T("startTime"),_T("0") + prev->End.GetASSFormated(true));
node->AddProperty(_T("xml:space"),_T("preserve"));
node->SetContent(_T(""));
node->SetNext(prevNode);
prevNode = node;
}
// Generate and insert node
node = new wxXmlNode(root,wxXML_ELEMENT_NODE,_T("TextSample"));
node->AddProperty(_T("startTime"),_T("0") + current->Start.GetASSFormated(true));
node->AddProperty(_T("xml:space"),_T("preserve"));
node->SetContent(current->Text);
node->SetNext(prevNode);
prevNode = node;
// Set as previous
prev = current;
i++;
}
else throw _T("Unexpected line type");
}
// Save XML
//prevNode->SetNext(NULL);
doc.Save(filename);
// Clear
ClearCopy();
}
///////////////////////
// Convert line to TTXT
void TTXTSubtitleFormat::DialogueToTTXT(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->StripTags();
// 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
current->Text.Replace(_T("\\n"),_T("\r\n"),true);
current->Text.Replace(_T("\\N"),_T("\r\n"),true);
while (current->Text.Replace(_T("\r\n\r\n"),_T("\r\n"),true));
}
//////////////////////////////
// Converts whole file to TTXT
void TTXTSubtitleFormat::ConvertToTTXT () {
using std::list;
// Sort lines
Line->sort(LessByPointedToValue<AssEntry>());
// Prepare processing
list<AssEntry*>::iterator next;
list<AssEntry*>::iterator prev = Line->end();
AssTime lastTime;
// 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) {
DialogueToTTXT(current,prev);
notfirst = true;
prev = cur;
lastTime = current->End;
}
// Other line, delete it
else {
delete *cur;
Line->erase(cur);
}
}
// Insert blank line at the end
AssDialogue *diag = new AssDialogue();
diag->Start = lastTime;
diag->End.SetMS(lastTime.GetMS()+5000);
diag->group = _T("[Events]");
diag->Style = _T("Default");
diag->Comment = false;
diag->StartMS = diag->Start.GetMS();
Line->push_back(diag);
} }

View file

@ -39,12 +39,24 @@
/////////// ///////////
// Headers // Headers
#include "ass_dialogue.h"
#include "subtitle_format.h" #include "subtitle_format.h"
#include <wx/xml/xml.h>
////////////////////// //////////////////////
// TTXT reader/writer // TTXT reader/writer
class TTXTSubtitleFormat : public SubtitleFormat { class TTXTSubtitleFormat : public SubtitleFormat {
private:
int version;
AssDialogue *diag;
bool ProcessLine(wxXmlNode *node);
void ProcessHeader(wxXmlNode *node);
void ConvertToTTXT();
void DialogueToTTXT(AssDialogue *current,std::list<AssEntry*>::iterator prev);
public: public:
wxString GetName(); wxString GetName();
wxArrayString GetReadWildcards(); wxArrayString GetReadWildcards();