diff --git a/athenasub/include/athenasub/athenastring.h b/athenasub/include/athenasub/athenastring.h index 444a0938a..51ce8235c 100644 --- a/athenasub/include/athenasub/athenastring.h +++ b/athenasub/include/athenasub/athenastring.h @@ -57,6 +57,11 @@ namespace Athenasub { String(const basic_string& str); explicit String(const wchar_t* utf16); explicit String(const wxString& wxstring); + explicit String(char character); + explicit String(wchar_t character); + explicit String(int integer); + explicit String(float number); + explicit String(double number); wxString GetWxString() const; diff --git a/athenasub/include/athenasub/interfaces.h b/athenasub/include/athenasub/interfaces.h index 6436fddd7..22cd2da17 100644 --- a/athenasub/include/athenasub/interfaces.h +++ b/athenasub/include/athenasub/interfaces.h @@ -107,10 +107,6 @@ namespace Athenasub { protected: virtual void ProcessActionList(CActionList &actionList,int type=0) = 0; - virtual String GetUndoMessage(const String owner="") const = 0; - virtual String GetRedoMessage(const String owner="") const = 0; - virtual bool CanUndo(const String owner="") const = 0; - virtual bool CanRedo(const String owner="") const = 0; virtual void Undo(const String owner="") = 0; virtual void Redo(const String owner="") = 0; virtual void ActivateStack(ActionStack stack,bool isUndo,const String &owner) = 0; @@ -119,22 +115,29 @@ namespace Athenasub { virtual void Clear() = 0; virtual void Load(wxInputStream &input,Format format=Format(),const String encoding="") = 0; - virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") = 0; virtual void AddSection(String name) = 0; - virtual Section GetSection(String name) = 0; - virtual Section GetSectionByIndex(size_t index) = 0; + virtual Section GetMutableSection(String name) = 0; + virtual Section GetMutableSectionByIndex(size_t index) = 0; public: virtual ~IModel() {} + virtual Controller CreateController() = 0; + virtual void AddListener(View listener) = 0; + + virtual void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") const = 0; + + virtual String GetUndoMessage(const String owner="") const = 0; + virtual String GetRedoMessage(const String owner="") const = 0; + virtual bool CanUndo(const String owner="") const = 0; + virtual bool CanRedo(const String owner="") const = 0; + virtual ConstSection GetSection(String name) const = 0; virtual ConstSection GetSectionByIndex(size_t index) const = 0; virtual size_t GetSectionCount() const = 0; - virtual Controller CreateController()=0; - virtual Format GetFormat() const=0; - virtual void AddListener(View listener)=0; + virtual Format GetFormat() const = 0; }; @@ -314,7 +317,7 @@ namespace Athenasub { virtual String GetName() const = 0; virtual StringArray GetReadExtensions() const = 0; virtual StringArray GetWriteExtensions() const = 0; - virtual FormatHandler GetHandler(IModel &model) const = 0; + virtual FormatHandler GetHandler() const = 0; virtual bool CanStoreText() const = 0; virtual bool CanStoreImages() const = 0; @@ -340,8 +343,8 @@ namespace Athenasub { public: virtual ~IFormatHandler() {} - virtual void Load(wxInputStream &file,const String encoding) = 0; - virtual void Save(wxOutputStream &file,const String encoding) = 0; + virtual void Load(IModel &model,wxInputStream &file,const String encoding) = 0; + virtual void Save(const IModel &model,wxOutputStream &file,const String encoding) const = 0; }; diff --git a/athenasub/src/action.h b/athenasub/src/action.h index 95ce82a6d..548653574 100644 --- a/athenasub/src/action.h +++ b/athenasub/src/action.h @@ -49,7 +49,7 @@ namespace Athenasub { CAction(Model model); Model GetModel() const { return model; } - Section GetSection(String name) const { return model->GetSection(name); } + Section GetSection(String name) const { return model->GetMutableSection(name); } }; // Insert line diff --git a/athenasub/src/actionlist.cpp b/athenasub/src/actionlist.cpp index d7fccb9cd..8345c3236 100644 --- a/athenasub/src/actionlist.cpp +++ b/athenasub/src/actionlist.cpp @@ -125,7 +125,7 @@ void CActionList::RemoveLine(int position,const String section) // Insert a "modify line" action Entry CActionList::ModifyLine(int position,const String section) { - Section sect = Model(model)->GetSection(section); + Section sect = Model(model)->GetMutableSection(section); Entry entry = sect->GetEntry(position)->Clone(); Action action = Action (new ActionModify(model.lock(),entry,position,section,false)); AddAction(action); @@ -138,7 +138,7 @@ Entry CActionList::ModifyLine(int position,const String section) std::vector CActionList::ModifyLines(Selection selection,const String section) { // Get section - Section sect = Model(model)->GetSection(section); + Section sect = Model(model)->GetMutableSection(section); // Generate entries std::vector entries(selection->GetCount()); diff --git a/athenasub/src/athenastring.cpp b/athenasub/src/athenastring.cpp index 3c678129e..4e454955b 100644 --- a/athenasub/src/athenastring.cpp +++ b/athenasub/src/athenastring.cpp @@ -82,6 +82,39 @@ String::String(const wxString& wxstring) } +String::String(char character) +{ + *this = std::string(character,1); +} + + +String::String(wchar_t character) +{ + wchar_t tmp[2]; + tmp[0] = character; + tmp[1] = 0; + *this = String(tmp); +} + + +String::String(int integer) +{ + *this = IntegerToString(integer); +} + + +String::String(float number) +{ + *this = FloatToString(number); +} + + +String::String(double number) +{ + *this = FloatToString(number); +} + + Character* String::GetCharPointer(size_t pos) { return &operator[](pos); diff --git a/athenasub/src/controller.cpp b/athenasub/src/controller.cpp index 8f86ac119..ac50e7684 100644 --- a/athenasub/src/controller.cpp +++ b/athenasub/src/controller.cpp @@ -148,7 +148,7 @@ ConstStyle CController::GetStyle(String name) const // Get section Style dummy = CreateStyle(); String section = dummy->GetDefaultGroup(); - Section sect = model->GetSection(section); + ConstSection sect = model->GetSection(section); if (!sect) THROW_ATHENA_EXCEPTION(Exception::Invalid_Section); // Return from index @@ -160,7 +160,7 @@ ConstStyle CController::GetStyle(String name) const // Get an entry ConstEntry CController::GetEntry(size_t n,String section) const { - Section sect = model->GetSection(section); + ConstSection sect = model->GetSection(section); if (!sect) THROW_ATHENA_EXCEPTION(Exception::Invalid_Section); return sect->GetEntry(n); } diff --git a/athenasub/src/format_handler.h b/athenasub/src/format_handler.h index 3f13807ee..872ac9743 100644 --- a/athenasub/src/format_handler.h +++ b/athenasub/src/format_handler.h @@ -42,24 +42,21 @@ namespace Athenasub { // Format handler interface class CFormatHandler : public IFormatHandler { - private: - IModel& model; - protected: virtual ~CFormatHandler() {} - IModel& GetModel() const { return model; } - - void AddSection(String name) { model.AddSection(name); } - Section GetSection(String name) const { return model.GetSection(name); } - Section GetSectionByIndex(size_t index) const { return model.GetSectionByIndex(index); } - size_t GetSectionCount() const { return model.GetSectionCount(); } + void AddSection(IModel &model,String name) const { model.AddSection(name); } + ConstSection GetSection(const IModel &model,String name) const { return model.GetSection(name); } + ConstSection GetSectionByIndex(const IModel &model,size_t index) const { return model.GetSectionByIndex(index); } + Section GetSection(IModel &model,String name) const { return model.GetMutableSection(name); } + Section GetSectionByIndex(IModel &model,size_t index) const { return model.GetMutableSectionByIndex(index); } + size_t GetSectionCount(const IModel &model) const { return model.GetSectionCount(); } public: - CFormatHandler(IModel& _model) : model(_model) {} + //CFormatHandler(IModel& _model) : model(_model) {} - virtual void Load(wxInputStream &file,const String encoding) = 0; - virtual void Save(wxOutputStream &file,const String encoding) = 0; + virtual void Load(IModel &model,wxInputStream &file,const String encoding) = 0; + virtual void Save(const IModel &model,wxOutputStream &file,const String encoding) const = 0; }; } diff --git a/athenasub/src/formats/format_ass.cpp b/athenasub/src/formats/format_ass.cpp index 452489dbd..e02b8c5e3 100644 --- a/athenasub/src/formats/format_ass.cpp +++ b/athenasub/src/formats/format_ass.cpp @@ -90,8 +90,8 @@ StringArray FormatASS2::GetWriteExtensions() const /////////////// // Constructor -FormatHandlerASS::FormatHandlerASS(CModel &_model,int version) -: CFormatHandler(_model), formatVersion(version) +FormatHandlerASS::FormatHandlerASS(int version) +: CFormatHandler(), formatVersion(version) { } @@ -105,7 +105,7 @@ FormatHandlerASS::~FormatHandlerASS() /////////////// // Load a file -void FormatHandlerASS::Load(wxInputStream &file,const String encoding) +void FormatHandlerASS::Load(IModel &model,wxInputStream &file,const String encoding) { // Make text file reader TextFileReader reader(file,encoding); @@ -127,10 +127,10 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding) ProcessGroup(cur,curGroup,version); // Insert group if it doesn't already exist - if (prevGroup != curGroup) section = GetSection(curGroup); + if (prevGroup != curGroup) section = GetSection(model,curGroup); if (!section) { - AddSection(curGroup); - section = GetSection(curGroup); + AddSection(model,curGroup); + section = GetSection(model,curGroup); } // Skip [] lines @@ -142,13 +142,13 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding) } // Ensure validity - MakeValid(); + MakeValid(model); } ///////////////////// // Save file to disc -void FormatHandlerASS::Save(wxOutputStream &file,const String encoding) +void FormatHandlerASS::Save(const IModel& model,wxOutputStream &file,const String encoding) const { // Make text file writer TextFileWriter writer(file,encoding); @@ -162,9 +162,9 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding) sections.push_back("Graphics"); // Look for remaining sections - size_t totalSections = GetSectionCount(); + size_t totalSections = GetSectionCount(model); for (size_t i=0;iGetName(); + String name = GetSectionByIndex(model,i)->GetName(); // If not found on the list, add to it if (find(sections.begin(),sections.end(),name) == sections.end()) { sections.push_back(name); @@ -175,7 +175,7 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding) size_t len = sections.size(); for (size_t i=0;iGetName(); @@ -371,15 +371,15 @@ void FormatHandlerASS::WriteSection(TextFileWriter &writer,Section section) /////////////////////// // Validate the format -void FormatHandlerASS::MakeValid() +void FormatHandlerASS::MakeValid(IModel &model) { // Only ASS supported right now if (formatVersion != 1) THROW_ATHENA_EXCEPTION(Exception::TODO); // Check for [Script Info] - Section section = GetSection("Script Info"); - if (!section) AddSection("Script Info"); - section = GetSection("Script Info"); + Section section = GetSection(model,"Script Info"); + if (!section) AddSection(model,"Script Info"); + section = GetSection(model,"Script Info"); if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error); // Check if necessary variables are available @@ -388,16 +388,16 @@ void FormatHandlerASS::MakeValid() section->SetProperty("ScriptType","v4.00+"); // Get [V4+ Styles] - section = GetSection("V4+ Styles"); - if (!section) AddSection("V4+ Styles"); - section = GetSection("V4+ Styles"); + section = GetSection(model,"V4+ Styles"); + if (!section) AddSection(model,"V4+ Styles"); + section = GetSection(model,"V4+ Styles"); if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error); section->SetProperty("Format","Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding"); // Get [Events] - section = GetSection("Events"); - if (!section) AddSection("Events"); - section = GetSection("Events"); + section = GetSection(model,"Events"); + if (!section) AddSection(model,"Events"); + section = GetSection(model,"Events"); if (!section) THROW_ATHENA_EXCEPTION(Exception::Internal_Error); section->SetProperty("Format","Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text"); } diff --git a/athenasub/src/formats/format_ass.h b/athenasub/src/formats/format_ass.h index 7a4aadf6d..f89be1d38 100644 --- a/athenasub/src/formats/format_ass.h +++ b/athenasub/src/formats/format_ass.h @@ -55,15 +55,15 @@ namespace Athenasub { Entry MakeEntry(const String &data,Section section,int version); void ProcessGroup(String cur,String &curGroup,int &version); - void WriteSection(TextFileWriter &writer,Section section); - void MakeValid(); + void WriteSection(TextFileWriter &writer,ConstSection section) const; + void MakeValid(IModel &model); public: - FormatHandlerASS(CModel &model,int version); + FormatHandlerASS(int version); ~FormatHandlerASS(); - void Load(wxInputStream &file,const String encoding); - void Save(wxOutputStream &file,const String encoding); + void Load(IModel &model,wxInputStream &file,const String encoding); + void Save(const IModel &model,wxOutputStream &file,const String encoding) const; }; // Advanced Substation Alpha format base class @@ -92,7 +92,7 @@ namespace Athenasub { // Substation Alpha class FormatSSA : public FormatASSFamily { public: - FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,0)); } + FormatHandler GetHandler() const { return FormatHandler(new FormatHandlerASS(0)); } String GetName() const { return "Substation Alpha"; } StringArray GetReadExtensions() const; StringArray GetWriteExtensions() const; @@ -101,7 +101,7 @@ namespace Athenasub { // Advanced Substation Alpha class FormatASS : public FormatASSFamily { public: - FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,1)); } + FormatHandler GetHandler() const { return FormatHandler(new FormatHandlerASS(1)); } String GetName() const { return "Advanced Substation Alpha"; } StringArray GetReadExtensions() const; StringArray GetWriteExtensions() const; @@ -110,7 +110,7 @@ namespace Athenasub { // Advanced Substation Alpha 2 class FormatASS2 : public FormatASSFamily { public: - FormatHandler GetHandler(IModel &model) const { return FormatHandler(new FormatHandlerASS((CModel&)model,2)); } + FormatHandler GetHandler() const { return FormatHandler(new FormatHandlerASS(2)); } String GetName() const { return "Advanced Substation Alpha 2"; } StringArray GetReadExtensions() const; StringArray GetWriteExtensions() const; diff --git a/athenasub/src/formats/format_ass_dialogue.cpp b/athenasub/src/formats/format_ass_dialogue.cpp index 9f300c513..2a8351432 100644 --- a/athenasub/src/formats/format_ass_dialogue.cpp +++ b/athenasub/src/formats/format_ass_dialogue.cpp @@ -202,3 +202,22 @@ String DialogueASS::ToText(int version) const buffer.SetSize(pos-1); return buffer; } + + +//////////////////////// +// Overloaded operators +bool DialogueASS::operator==(const DialogueASS& param) const +{ + if (time != param.time) return false; + if (text != param.text) return false; + if (margin != param.margin) return false; + if (layer != param.layer) return false; + if (isComment != param.isComment) return false; + return true; +} + +bool DialogueASS::operator!=(const DialogueASS& param) const +{ + return !(*this == param); +} + diff --git a/athenasub/src/formats/format_ass_dialogue.h b/athenasub/src/formats/format_ass_dialogue.h index 94102c731..cd7098854 100644 --- a/athenasub/src/formats/format_ass_dialogue.h +++ b/athenasub/src/formats/format_ass_dialogue.h @@ -93,6 +93,10 @@ namespace Athenasub { void SetStyle(const String &style) { text[1] = style; } void SetActor(const String &actor) { text[2] = actor; } void SetUserField(const String &userField) { text[3] = userField; } + + // Operator overloading + bool operator==(const DialogueASS& param) const; + bool operator!=(const DialogueASS& param) const; }; } diff --git a/athenasub/src/model.cpp b/athenasub/src/model.cpp index 77f73ca31..3e67591a4 100644 --- a/athenasub/src/model.cpp +++ b/athenasub/src/model.cpp @@ -118,14 +118,14 @@ void CModel::Load(wxInputStream &input,const Format _format,const String encodin } // Get handler - FormatHandler handler = _format->GetHandler(*this); + FormatHandler handler = _format->GetHandler(); if (!handler) THROW_ATHENA_EXCEPTION(Exception::No_Format_Handler); // Clear the model first Clear(); // Load - handler->Load(input,encoding); + handler->Load(*this,input,encoding); // Set the format format = _format; @@ -134,7 +134,7 @@ void CModel::Load(wxInputStream &input,const Format _format,const String encodin ////////////////// // Save subtitles -void CModel::Save(wxOutputStream &output,const Format _format,const String encoding) +void CModel::Save(wxOutputStream &output,const Format _format,const String encoding) const { // Use another format if (_format && _format != format) { @@ -143,11 +143,11 @@ void CModel::Save(wxOutputStream &output,const Format _format,const String encod } // Get handler - FormatHandler handler = format->GetHandler(*this); + FormatHandler handler = format->GetHandler(); if (!handler) THROW_ATHENA_EXCEPTION(Exception::No_Format_Handler); // Load - handler->Save(output,encoding); + handler->Save(*this,output,encoding); } @@ -155,7 +155,7 @@ void CModel::Save(wxOutputStream &output,const Format _format,const String encod // Inserts a new section void CModel::AddSection(String name) { - Section prev = GetSection(name); + ConstSection prev = GetSection(name); if (prev) THROW_ATHENA_EXCEPTION(Exception::Section_Already_Exists); sections.push_back(Section(new CSection(name))); } @@ -172,7 +172,7 @@ ConstSection CModel::GetSection(String name) const return SectionPtr(); } -Section CModel::GetSection(String name) +Section CModel::GetMutableSection(String name) { size_t len = sections.size(); for (size_t i=0;i weakThis; @@ -80,22 +81,24 @@ namespace Athenasub { void Clear(); void Load(wxInputStream &input,Format format=Format(),const String encoding=""); - void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8"); void AddSection(String name); - ConstSection GetSection(String name) const; - Section GetSection(String name); - ConstSection GetSectionByIndex(size_t index) const; - Section GetSectionByIndex(size_t index); - size_t GetSectionCount() const; + Section GetMutableSection(String name); + Section GetMutableSectionByIndex(size_t index); + + void SetWeakPtr(weak_ptr ptr) { weakThis = ptr; } public: CModel(); Controller CreateController(); Format GetFormat() const { return format; } - void AddListener(View listener); - void SetWeakPtr(weak_ptr ptr) { weakThis = ptr; } + void AddListener(View listener); + void Save(wxOutputStream &output,Format format=Format(),const String encoding="UTF-8") const; + + ConstSection GetSection(String name) const; + ConstSection GetSectionByIndex(size_t index) const; + size_t GetSectionCount() const; }; typedef shared_ptr ModelPtr; diff --git a/athenasub/test/src/main.cpp b/athenasub/test/src/main.cpp index 77499f529..285b2ec52 100644 --- a/athenasub/test/src/main.cpp +++ b/athenasub/test/src/main.cpp @@ -92,9 +92,9 @@ int main() // Issue an action #ifdef WXDEBUG - int n = 1000; -#else int n = 1; +#else + int n = 1000; #endif cout << "Executing action " << n << " times... "; timer.Start(); @@ -126,7 +126,7 @@ int main() cout << "Done in " << timer.Time() << " ms.\n"; // Undo - n = 1000; + n = 10; cout << "Undoing and redoing " << n << " times... "; timer.Start(); for (int i=0;i