diff --git a/aegilib/aegilib.vcproj b/aegilib/aegilib.vcproj
index b63836671..d1213ac3a 100644
--- a/aegilib/aegilib.vcproj
+++ b/aegilib/aegilib.vcproj
@@ -324,6 +324,14 @@
RelativePath=".\src\text_file_reader.h"
>
+
+
+
+
diff --git a/aegilib/include/aegilib/format_handler.h b/aegilib/include/aegilib/format_handler.h
index 2ad27b56f..f24424e74 100644
--- a/aegilib/include/aegilib/format_handler.h
+++ b/aegilib/include/aegilib/format_handler.h
@@ -46,6 +46,7 @@ namespace Aegilib {
public:
virtual void Load(wxInputStream &file,const String encoding) = 0;
+ virtual void Save(wxOutputStream &file,const String encoding) = 0;
};
typedef shared_ptr FormatHandlerPtr;
diff --git a/aegilib/include/aegilib/model.h b/aegilib/include/aegilib/model.h
index c28a178f6..500dae3d7 100644
--- a/aegilib/include/aegilib/model.h
+++ b/aegilib/include/aegilib/model.h
@@ -35,6 +35,7 @@
#pragma once
#include
+#include
#include
#include "manipulator.h"
#include "section.h"
@@ -56,7 +57,7 @@ namespace Aegilib {
typedef shared_ptr FormatPtr;
private:
- std::list sections;
+ std::vector sections;
ActionStack undoStack;
ActionStack redoStack;
ViewList listeners;
@@ -75,8 +76,10 @@ namespace Aegilib {
void LoadFile(const String filename,const String encoding=L"");
void SaveFile(const String filename,const String encoding=L"UTF-8");
- SectionPtr GetSection(String name) const;
void AddSection(String name);
+ SectionPtr GetSection(String name) const;
+ SectionPtr GetSectionByIndex(size_t index) const;
+ size_t GetSectionCount() const;
bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const;
diff --git a/aegilib/include/aegilib/section.h b/aegilib/include/aegilib/section.h
index de952667b..d51eb6fe0 100644
--- a/aegilib/include/aegilib/section.h
+++ b/aegilib/include/aegilib/section.h
@@ -44,9 +44,8 @@ namespace Aegilib {
// Section class
class Section {
- friend class shared_ptr;
private:
- std::list entries;
+ std::vector entries;
std::map properties;
String name;
@@ -54,17 +53,24 @@ namespace Aegilib {
Section(String name);
~Section() {}
- const String& GetName() const { return name; }
+ // Section name
String SetName(const String& newName) { name = newName; }
+ const String& GetName() const { return name; }
+ // Script properties
void SetProperty(const String &key,const String &value);
void UnsetProperty(const String &key);
String GetProperty(const String &key) const;
bool HasProperty(const String &key) const;
- size_t PropertyCount() const;
+ size_t GetPropertyCount() const;
String GetPropertyName(size_t index) const;
+ // Entries
void AddEntry(SectionEntryPtr entry);
+ void RemoveEntryByIndex(size_t index);
+ void RemoveEntry(SectionEntryPtr entry);
+ SectionEntryConstPtr GetEntry(size_t index) const;
+ size_t GetEntryCount() const;
};
typedef shared_ptr SectionPtr;
diff --git a/aegilib/include/aegilib/section_entry.h b/aegilib/include/aegilib/section_entry.h
index ec6a54921..6451765e5 100644
--- a/aegilib/include/aegilib/section_entry.h
+++ b/aegilib/include/aegilib/section_entry.h
@@ -49,18 +49,24 @@ namespace Aegilib {
};
// Prototypes
- class SectionEntryPlain;
- typedef shared_ptr SectionEntryPlainPtr;
- class SectionEntryDialogue;
- typedef shared_ptr SectionEntryDialoguePtr;
- class SectionEntryStyle;
- typedef shared_ptr SectionEntryStylePtr;
- class SectionEntryFile;
- typedef shared_ptr SectionEntryFilePtr;
- class SectionEntryRaw;
- typedef shared_ptr SectionEntryRawPtr;
class SectionEntry;
+ class SectionEntryPlain;
+ class SectionEntryDialogue;
+ class SectionEntryStyle;
+ class SectionEntryFile;
+ class SectionEntryRaw;
typedef shared_ptr SectionEntryPtr;
+ typedef shared_ptr SectionEntryPlainPtr;
+ typedef shared_ptr SectionEntryDialoguePtr;
+ typedef shared_ptr SectionEntryStylePtr;
+ typedef shared_ptr SectionEntryFilePtr;
+ typedef shared_ptr SectionEntryRawPtr;
+ typedef shared_ptr SectionEntryConstPtr;
+ typedef shared_ptr SectionEntryPlainConstPtr;
+ typedef shared_ptr SectionEntryDialogueConstPtr;
+ typedef shared_ptr SectionEntryStyleConstPtr;
+ typedef shared_ptr SectionEntryFileConstPtr;
+ typedef shared_ptr SectionEntryRawConstPtr;
// Section entry class
class SectionEntry {
@@ -72,6 +78,7 @@ namespace Aegilib {
virtual SectionEntryType GetType() const =0;
static const SectionEntryPlainPtr GetAsPlain(const SectionEntryPtr &ptr);
static const SectionEntryDialoguePtr GetAsDialogue(const SectionEntryPtr &ptr);
+ static const SectionEntryDialogueConstPtr GetAsDialogue(const SectionEntryConstPtr &ptr);
static const SectionEntryStylePtr GetAsStyle(const SectionEntryPtr &ptr);
static const SectionEntryFilePtr GetAsFile(const SectionEntryPtr &ptr);
static const SectionEntryRawPtr GetAsRaw(const SectionEntryPtr &ptr);
diff --git a/aegilib/src/formats/format_ass.cpp b/aegilib/src/formats/format_ass.cpp
index 79c8bf60f..a79ab6936 100644
--- a/aegilib/src/formats/format_ass.cpp
+++ b/aegilib/src/formats/format_ass.cpp
@@ -33,9 +33,11 @@
// Contact: mailto:amz@aegisub.net
//
+#include "section.h"
#include "model.h"
#include "format_ass.h"
#include "../text_file_reader.h"
+#include "../text_file_writer.h"
#include
#include
using namespace Aegilib;
@@ -78,10 +80,6 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
// Make text file reader
TextFileReader reader(file,encoding);
- // Debug
- using namespace std;
- cout << endl << "Dumping file:" << endl;
-
// Variables
int version = 1;
wxString curGroup = L"-";
@@ -111,17 +109,44 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
SectionEntryPtr entry = MakeEntry(cur,section,version);
if (entry) section->AddEntry(entry);
}
+}
- // Debug
- cout << "\nFinished reading file with version=" << version << ".\n";
- cout << "Dumping properties:\n";
- section = model.GetSection(_T("Script Info"));
- size_t n = section->PropertyCount();
- for (size_t i=0;iGetPropertyName(i);
- cout << name.mb_str(wxConvUTF8) << "=" << section->GetProperty(name).mb_str(wxConvUTF8) << endl;
+
+/////////////////////
+// Save file to disc
+void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
+{
+ // Make text file writer
+ TextFileWriter writer(file,encoding);
+
+ // Set up list of sections to write
+ wxArrayString sections;
+ sections.Add(L"Script Info");
+ sections.Add(L"V4+ Styles");
+ sections.Add(L"Events");
+ sections.Add(L"Fonts");
+ sections.Add(L"Graphics");
+
+ // Look for remaining sections
+ size_t totalSections = model.GetSectionCount();
+ for (size_t i=0;iGetName();
+ if (sections.Index(name,false,false) == wxNOT_FOUND) sections.Add(name);
+ }
+
+ // Write sections
+ size_t len = sections.size();
+ for (size_t i=0;iGetName() + _T("]"));
+
+ // Write properties
+ size_t props = section->GetPropertyCount();
+ for (size_t i=0;iGetPropertyName(i);
+ writer.WriteLineToFile(name + _T(": ") + section->GetProperty(name));
+ }
+
+ // Write contents
+ size_t entries = section->GetEntryCount();
+ for (size_t i=0;iGetEntry(i);
+ shared_ptr serial = dynamic_pointer_cast(entry);
+ writer.WriteLineToFile(serial->ToText());
+ }
+}
diff --git a/aegilib/src/formats/format_ass.h b/aegilib/src/formats/format_ass.h
index e229bb617..f7cd072c7 100644
--- a/aegilib/src/formats/format_ass.h
+++ b/aegilib/src/formats/format_ass.h
@@ -44,19 +44,29 @@ namespace Aegilib {
// Prototypes
class Model;
+ class TextFileWriter;
+
+ class SerializeText {
+ public:
+ virtual ~SerializeText(){}
+ virtual String ToText() const=0;
+ };
// Advanced Substation Alpha format handler
class FormatHandlerASS : public FormatHandler {
private:
+ Model &model;
+
SectionEntryPtr MakeEntry(const String &data,SectionPtr section,int version);
void ProcessGroup(String cur,String &curGroup,int &version);
- Model &model;
+ void WriteSection(TextFileWriter &writer,SectionPtr section);
public:
FormatHandlerASS(Model &model);
~FormatHandlerASS();
void Load(wxInputStream &file,const String encoding);
+ void Save(wxOutputStream &file,const String encoding);
};
// Advanced Substation Alpha format
@@ -76,7 +86,7 @@ namespace Aegilib {
};
// Dialogue
- class DialogueASS : public SectionEntryDialogue {
+ class DialogueASS : public SectionEntryDialogue, public SerializeText {
private:
String text;
String style;
@@ -88,6 +98,7 @@ namespace Aegilib {
bool isComment;
bool Parse(String data,int version);
+ String ToText() const;
public:
// Constructors
@@ -123,7 +134,7 @@ namespace Aegilib {
};
// Style
- class StyleASS : public SectionEntryStyle {
+ class StyleASS : public SectionEntryStyle, public SerializeText {
private:
String name;
String font;
@@ -152,6 +163,7 @@ namespace Aegilib {
bool Parse(String data,int version);
int AlignSSAtoASS(int ssaAlignment);
int AlignASStoSSA(int assAlignment);
+ String ToText() const;
public:
// Constructors
diff --git a/aegilib/src/formats/format_ass_dialogue.cpp b/aegilib/src/formats/format_ass_dialogue.cpp
index 476ec2519..3131da4d9 100644
--- a/aegilib/src/formats/format_ass_dialogue.cpp
+++ b/aegilib/src/formats/format_ass_dialogue.cpp
@@ -134,3 +134,12 @@ bool DialogueASS::Parse(wxString rawData, int version)
return true;
}
+
+
+/////////////
+// Serialize
+String DialogueASS::ToText() const
+{
+ String final = L"Dialogue";
+ return final;
+}
diff --git a/aegilib/src/formats/format_ass_style.cpp b/aegilib/src/formats/format_ass_style.cpp
index 50ac442e4..26016e728 100644
--- a/aegilib/src/formats/format_ass_style.cpp
+++ b/aegilib/src/formats/format_ass_style.cpp
@@ -163,3 +163,12 @@ int StyleASS::AlignASStoSSA(int assAlignment)
// TODO
return assAlignment;
}
+
+
+/////////////
+// Serialize
+String StyleASS::ToText() const
+{
+ String final = L"Style";
+ return final;
+}
diff --git a/aegilib/src/model.cpp b/aegilib/src/model.cpp
index ef6fbe472..5b5381fa4 100644
--- a/aegilib/src/model.cpp
+++ b/aegilib/src/model.cpp
@@ -109,10 +109,20 @@ void Model::Load(wxInputStream &input,const FormatPtr format,const String encodi
// Save subtitles
void Model::Save(wxOutputStream &output,const FormatPtr format,const String encoding)
{
- (void) output;
- (void) format;
- (void) encoding;
- // TODO
+ // Autodetect format
+ if (format == NULL) {
+ // TODO
+
+ // No format found
+ throw Exception(Exception::No_Format_Handler);
+ }
+
+ // Get handler
+ FormatHandlerPtr handler = format->GetHandler(*this);
+ if (!handler) throw Exception(Exception::No_Format_Handler);
+
+ // Load
+ handler->Save(output,encoding);
}
@@ -136,18 +146,6 @@ void Model::SaveFile(const String filename,const String encoding)
}
-//////////////////
-// Gets a section
-SectionPtr Model::GetSection(String name) const
-{
- std::list::const_iterator cur;
- for (cur=sections.begin();cur!=sections.end();cur++) {
- if ((*cur)->GetName() == name) return *cur;
- }
- return SectionPtr();
-}
-
-
/////////////////////////
// Inserts a new section
void Model::AddSection(String name)
@@ -156,3 +154,31 @@ void Model::AddSection(String name)
if (prev) throw Exception(Exception::Section_Already_Exists);
sections.push_back(SectionPtr(new Section(name)));
}
+
+
+//////////////////
+// Gets a section
+SectionPtr Model::GetSection(String name) const
+{
+ size_t len = sections.size();
+ for (size_t i=0;iGetName() == name) return sections[i];
+ }
+ return SectionPtr();
+}
+
+
+////////////////////////
+// Get section by index
+SectionPtr Model::GetSectionByIndex(size_t index) const
+{
+ return sections.at(index);
+}
+
+
+/////////////////////
+// Get section count
+size_t Model::GetSectionCount() const
+{
+ return sections.size();
+}
diff --git a/aegilib/src/section.cpp b/aegilib/src/section.cpp
index 7eeff08b7..d0b80d38e 100644
--- a/aegilib/src/section.cpp
+++ b/aegilib/src/section.cpp
@@ -53,6 +53,32 @@ void Section::AddEntry(SectionEntryPtr entry)
entries.push_back(entry);
}
+void Section::RemoveEntryByIndex(size_t index)
+{
+ entries.erase(entries.begin()+index);
+}
+
+void Section::RemoveEntry(SectionEntryPtr entry)
+{
+ size_t len = entries.size();
+ for (size_t i=0;i(ptr);
}
+const SectionEntryDialogueConstPtr SectionEntry::GetAsDialogue(const SectionEntryConstPtr &ptr)
+{
+ return dynamic_pointer_cast(ptr);
+}
const SectionEntryStylePtr SectionEntry::GetAsStyle(const SectionEntryPtr &ptr)
{
return dynamic_pointer_cast(ptr);
diff --git a/aegilib/src/text_file_writer.cpp b/aegilib/src/text_file_writer.cpp
index a838abbe7..575881080 100644
--- a/aegilib/src/text_file_writer.cpp
+++ b/aegilib/src/text_file_writer.cpp
@@ -38,76 +38,38 @@
// Headers
#include
#include "text_file_writer.h"
+using namespace Aegilib;
///////////////
// Constructor
-TextFileWriter::TextFileWriter(Aegilib::String _filename,Aegilib::String enc) {
+TextFileWriter::TextFileWriter(wxOutputStream &stream,String enc)
+: file(stream)
+{
// Setup
- open = false;
- customConv = false;
IsFirst = true;
- filename = _filename;
// Set encoding
encoding = enc;
- if (encoding == _T("Local")) conv = &wxConvLocal;
+ if (encoding == _T("Local")) conv = shared_ptr (wxConvCurrent,NullDeleter());
else {
if (encoding.IsEmpty()) encoding = _T("UTF-8");
if (encoding == _T("US-ASCII")) encoding = _T("ISO-8859-1");
- conv = new wxCSConv(encoding);
- customConv = true;
+ conv = shared_ptr (new wxCSConv(encoding));
IsUnicode = encoding.Left(3) == _T("UTF");
}
-
- // Open file
- Open();
}
//////////////
// Destructor
TextFileWriter::~TextFileWriter() {
- Close();
-}
-
-
-/////////////
-// Open file
-void TextFileWriter::Open() {
- // Open file
- if (open) return;
-#ifdef WIN32
- file.open(filename.wc_str(),std::ios::out | std::ios::binary | std::ios::trunc);
-#else
- file.open(wxFNCONV(filename),std::ios::out | std::ios::binary | std::ios::trunc);
-#endif
- if (!file.is_open()) {
- throw _T("Failed opening file for writing.");
- }
- open = true;
-
- // Set encoding
- SetEncoding();
-}
-
-
-//////////////
-// Close file
-void TextFileWriter::Close() {
- if (!open) return;
- file.close();
- open = false;
- if (customConv) delete conv;
}
/////////////////
// Write to file
void TextFileWriter::WriteLineToFile(Aegilib::String line,bool addLineBreak) {
- // Make sure it's loaded
- if (!open) Open();
-
// Add line break
wxString temp = line;
if (addLineBreak) temp += _T("\r\n");
@@ -125,7 +87,7 @@ void TextFileWriter::WriteLineToFile(Aegilib::String line,bool addLineBreak) {
if (!buf.data())
return;
size_t len = wcslen(buf.data());
- file.write((const char*)buf.data(),(std::streamsize)len*sizeof(wchar_t));
+ file.Write((const char*)buf.data(),(std::streamsize)len*sizeof(wchar_t));
}
// 8-bit
@@ -134,7 +96,7 @@ void TextFileWriter::WriteLineToFile(Aegilib::String line,bool addLineBreak) {
if (!buf.data())
return;
size_t len = strlen(buf.data());
- file.write(buf.data(),(std::streamsize)len);
+ file.Write(buf.data(),(std::streamsize)len);
}
}
diff --git a/aegilib/src/text_file_writer.h b/aegilib/src/text_file_writer.h
index c1d156cac..8d24562ba 100644
--- a/aegilib/src/text_file_writer.h
+++ b/aegilib/src/text_file_writer.h
@@ -34,42 +34,28 @@
//
-#ifndef TEXT_FILE_WRITER_H
-#define TEXT_FILE_WRITER_H
+#pragma once
+#include "aegilib.h"
+#include
-///////////
-// Headers
-#include
-#include
-#include
+namespace Aegilib {
+ class TextFileWriter {
+ private:
+ wxString encoding;
+ wxOutputStream &file;
+ shared_ptr conv;
+ bool Is16;
+ bool IsFirst;
+ bool IsUnicode;
-/////////
-// Class
-class TextFileWriter {
-private:
- wxString filename;
- wxString encoding;
- std::ofstream file;
+ void SetEncoding();
- wxMBConv *conv;
- bool customConv;
- bool open;
- bool Is16;
- bool IsFirst;
- bool IsUnicode;
+ public:
+ TextFileWriter(wxOutputStream &stream,String encoding=_T(""));
+ ~TextFileWriter();
- void Open();
- void Close();
- void SetEncoding();
-
-public:
- TextFileWriter(Aegilib::String filename,Aegilib::String encoding=_T(""));
- ~TextFileWriter();
-
- void WriteLineToFile(Aegilib::String line,bool addLineBreak=true);
+ void WriteLineToFile(Aegilib::String line,bool addLineBreak=true);
+ };
};
-
-
-#endif