Gorgonsub is now capable of doing some simple manipulation (i.e. line insertion).

Originally committed to SVN as r2048.
This commit is contained in:
Rodrigo Braz Monteiro 2008-03-14 02:02:48 +00:00
parent bb425f8a86
commit b073b7d28d
21 changed files with 404 additions and 145 deletions

View file

@ -160,6 +160,10 @@
RelativePath=".\include\aegilib\action.h"
>
</File>
<File
RelativePath=".\include\aegilib\actionlist.h"
>
</File>
<File
RelativePath=".\include\aegilib\colour.h"
>
@ -196,10 +200,6 @@
RelativePath=".\include\aegilib\gorgontime.h"
>
</File>
<File
RelativePath=".\include\aegilib\manipulator.h"
>
</File>
<File
RelativePath=".\include\aegilib\model.h"
>
@ -253,7 +253,11 @@
>
</File>
<File
RelativePath=".\src\manipulator.cpp"
RelativePath=".\src\actionlist.cpp"
>
</File>
<File
RelativePath=".\src\controller.cpp"
>
</File>
<File

View file

@ -34,6 +34,7 @@
//
#pragma once
#include "gorgonstring.h"
namespace Gorgonsub {
// The different types of actions available
@ -48,14 +49,16 @@ namespace Gorgonsub {
private:
ActionType type;
shared_ptr<void> data;
String section;
int par1;
public:
Action();
Action(ActionType type,shared_ptr<void> data,int par1);
Action(ActionType type,shared_ptr<void> data,const String &section,int par1);
ActionType GetType() { return type; }
shared_ptr<void> GetData() { return data; }
int GetLineNumber() { return par1; }
ActionType GetType() const { return type; }
shared_ptr<void> GetData() const { return data; }
int GetLineNumber() const { return par1; }
String GetSection() const { return section; }
};
};

View file

@ -37,13 +37,17 @@
#include <list>
#include "action.h"
#include "gorgonstring.h"
#include "section_entry.h"
namespace Gorgonsub {
// Manipulator class
class Manipulator {
// Prototypes
class Controller;
// ActionList class
class ActionList {
friend class Model;
friend class std::list<Manipulator>;
friend class Controller;
private:
String actionName;
@ -51,14 +55,18 @@ namespace Gorgonsub {
std::list<Action> actions;
bool valid;
Manipulator();
ActionList();
ActionList(Model &model,const String actionName);
void Start(const String actionName);
public:
Manipulator(Model &model,String actionName);
~Manipulator();
~ActionList();
void AddAction(const Action &action);
void Flush();
void Finish();
void InsertLine(SectionEntryPtr line,int position=-1,const String section=L"");
};
typedef shared_ptr<ActionList> ActionListPtr;
};

View file

@ -0,0 +1,66 @@
// Copyright (c) 2008, 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/GORGONSUB
//
// Website: http://www.aegisub.net
// Contact: mailto:amz@aegisub.net
//
#pragma once
#include "gorgonstring.h"
#include "tr1.h"
#include "format.h"
namespace Gorgonsub {
// Prototypes
class Model;
class ActionList;
typedef shared_ptr<ActionList> ActionListPtr;
// Controller class
class Controller {
private:
Model &model;
public:
Controller (Model &model);
ActionListPtr CreateActionList(const String title);
void LoadFile(const String filename,const String encoding=L"");
void SaveFile(const String filename,const String encoding=L"UTF-8");
SectionEntryDialoguePtr CreateDialogue();
SectionEntryStylePtr CreateStyle();
const FormatPtr GetFormat() const;
};
};

View file

@ -46,12 +46,13 @@ namespace Gorgonsub {
enum ExceptionList {
Unknown,
No_Format_Handler,
Invalid_Manipulator,
Invalid_ActionList,
Section_Already_Exists,
Unknown_Format,
Parse_Error,
Unsupported_Format_Feature,
Invalid_Token
Invalid_Token,
TODO
};
Exception(ExceptionList code);

View file

@ -36,6 +36,7 @@
#pragma once
#include "gorgonstring.h"
#include "tr1.h"
#include "section_entry.h"
namespace Gorgonsub {
// Prototypes
@ -65,6 +66,9 @@ namespace Gorgonsub {
virtual int GetTimingPrecision() const { return 10; } // In milliseconds
virtual int GetMaxTime() const { return 36000000-10; } // In milliseconds, default 9h 59min 59.99s
virtual SectionEntryDialoguePtr CreateDialogue() const = 0;
virtual SectionEntryStylePtr CreateStyle() const = 0;
};
typedef shared_ptr<Format> FormatPtr;

View file

@ -35,16 +35,29 @@
#pragma once
#include "gorgonstring.h"
#include "model.h"
#include "tr1.h"
namespace Gorgonsub {
// Format handler interface
class FormatHandler {
private:
Model &model;
protected:
virtual ~FormatHandler() {}
Model &GetModel() const { return model; }
void AddSection(String name) { model.AddSection(name); }
SectionPtr GetSection(String name) const { return model.GetSection(name); }
SectionPtr GetSectionByIndex(size_t index) const { return model.GetSectionByIndex(index); }
size_t GetSectionCount() const { return model.GetSectionCount(); }
public:
FormatHandler(Model &_model) : model(_model) {}
virtual void Load(wxInputStream &file,const String encoding) = 0;
virtual void Save(wxOutputStream &file,const String encoding) = 0;
};

View file

@ -44,7 +44,7 @@
#include "format.h"
#include "format_handler.h"
#include "format_manager.h"
#include "manipulator.h"
#include "actionlist.h"
#include "section.h"
#include "section_entry_dialogue.h"
#include "section_entry_style.h"

View file

@ -37,7 +37,7 @@
#include <list>
#include <vector>
#include <wx/wfstream.h>
#include "manipulator.h"
#include "actionlist.h"
#include "section.h"
namespace Gorgonsub {
@ -51,9 +51,12 @@ namespace Gorgonsub {
// Model class
// Stores the subtitle data
class Model {
friend class Manipulator;
friend class FormatHandler;
friend class ActionList;
friend class Controller;
typedef std::list<ViewPtr> ViewList;
typedef std::list<const Manipulator> ActionStack;
typedef std::list<ActionListPtr> ActionStack;
typedef shared_ptr<Format> FormatPtr;
private:
@ -62,30 +65,31 @@ namespace Gorgonsub {
ActionStack redoStack;
ViewList listeners;
bool readOnly;
FormatPtr format;
void ProcessActionList(const ActionList &actionList,bool insertInStack);
void DoAction(const Action &action);
ActionListPtr CreateAntiActionList(const ActionListPtr &manipulator);
bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const;
bool Undo(const String owner=L"");
bool Redo(const String owner=L"");
void ProcessActionList(const Manipulator &actionList,bool insertInStack);
Manipulator CreateAntiManipulator(const Manipulator &manipulator);
void DispatchNotifications(const Notification &notification) const;
public:
const Format& GetFormat() const;
void AddListener(ViewPtr listener);
void Clear();
void Load(wxInputStream &input,const FormatPtr format=FormatPtr(),const String encoding=L"");
void Save(wxOutputStream &output,const FormatPtr format=FormatPtr(),const String encoding=L"UTF-8");
void LoadFile(const String filename,const String encoding=L"");
void SaveFile(const String filename,const String encoding=L"UTF-8");
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;
bool Undo(const String owner=L"");
bool Redo(const String owner=L"");
void Clear();
void Load(wxInputStream &input,const FormatPtr format=FormatPtr(),const String encoding=L"");
void Save(wxOutputStream &output,const FormatPtr format=FormatPtr(),const String encoding=L"UTF-8");
public:
const FormatPtr GetFormat() const { return format; }
void AddListener(ViewPtr listener);
};
};

View file

@ -66,7 +66,7 @@ namespace Gorgonsub {
String GetPropertyName(size_t index) const;
// Entries
void AddEntry(SectionEntryPtr entry);
void AddEntry(SectionEntryPtr entry,int pos=-1);
void RemoveEntryByIndex(size_t index);
void RemoveEntry(SectionEntryPtr entry);
SectionEntryConstPtr GetEntry(size_t index) const;

View file

@ -76,6 +76,8 @@ namespace Gorgonsub {
public:
virtual SectionEntryType GetType() const =0;
virtual String GetDefaultGroup() const =0;
static const SectionEntryPlainPtr GetAsPlain(const SectionEntryPtr &ptr);
static const SectionEntryDialoguePtr GetAsDialogue(const SectionEntryPtr &ptr);
static const SectionEntryDialogueConstPtr GetAsDialogue(const SectionEntryConstPtr &ptr);

View file

@ -46,9 +46,10 @@ Action::Action()
//////////////////////////////
// Initialization constructor
Action::Action(ActionType _type,shared_ptr<void> _data,int _par1)
Action::Action(ActionType _type,shared_ptr<void> _data,const String &_section,int _par1)
{
type = _type;
data = _data;
par1 = _par1;
section = _section;
}

View file

@ -39,34 +39,42 @@ using namespace Gorgonsub;
///////////////
// Constructor
Manipulator::Manipulator(Model &_model,String _actionName)
ActionList::ActionList(Model &_model,String _actionName)
: model(_model)
{
actionName = _actionName;
valid = true;
Start(_actionName);
}
//////////////
// Destructor
Manipulator::~Manipulator()
ActionList::~ActionList()
{
Flush();
}
//////////////////////////////
// Add an action to the queue
void Manipulator::AddAction(const Action &action)
void ActionList::AddAction(const Action &action)
{
if (!valid) throw Exception(Exception::Invalid_Manipulator);
if (!valid) throw Exception(Exception::Invalid_ActionList);
actions.push_back(action);
}
////////////////////////////////
// Flush the queue to the model
void Manipulator::Flush()
/////////////////////////////
// Starts performing actions
void ActionList::Start(const String name)
{
if (valid) Finish();
actionName = name;
valid = true;
}
////////////////////////
// Ends the action list
void ActionList::Finish()
{
if (valid) {
model.ProcessActionList(*this,false);
@ -74,3 +82,12 @@ void Manipulator::Flush()
valid = false;
}
}
//////////////////////////////////
// Create an "insert line" action
void ActionList::InsertLine(SectionEntryPtr line,int position,const String section)
{
Action action = Action(ACTION_INSERT,line,section,position);
AddAction(action);
}

View file

@ -0,0 +1,93 @@
// Copyright (c) 2008, 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/GORGONSUB
//
// Website: http://www.aegisub.net
// Contact: mailto:amz@aegisub.net
//
#include "Gorgonsub.h"
using namespace Gorgonsub;
///////////////
// Constructor
Controller::Controller(Model &_model)
: model(_model)
{
}
/////////////////////////
// Create an action list
ActionListPtr Controller::CreateActionList(const String title)
{
return ActionListPtr (new ActionList(model,title));
}
///////////////
// Load a file
void Controller::LoadFile(const String filename,const String encoding)
{
const FormatPtr handler = FormatManager::GetFormatFromFilename(filename,true);
wxFileInputStream stream(filename);
model.Load(stream,handler,encoding);
}
///////////////
// Save a file
void Controller::SaveFile(const String filename,const String encoding)
{
const FormatPtr handler = FormatManager::GetFormatFromFilename(filename,true);
wxFileOutputStream stream(filename);
model.Save(stream,handler,encoding);
}
//////////////
// Get format
const FormatPtr Controller::GetFormat() const
{
return model.GetFormat();
}
//////////////////
// Create entries
SectionEntryDialoguePtr Controller::CreateDialogue()
{
return GetFormat()->CreateDialogue();
}
SectionEntryStylePtr Controller::CreateStyle()
{
return GetFormat()->CreateStyle();
}

View file

@ -53,12 +53,13 @@ String Exception::GetMessage(int code)
switch (code) {
case Unknown: return L"Unknown.";
case No_Format_Handler: return L"Could not find a suitable format handler.";
case Invalid_Manipulator: return L"Invalid manipulator.";
case Invalid_ActionList: return L"Invalid manipulator.";
case Section_Already_Exists: return L"The specified section already exists in this model.";
case Unknown_Format: return L"The specified file format is unknown.";
case Parse_Error: return L"Parse error.";
case Unsupported_Format_Feature: return L"This feature is not supported by this format.";
case Invalid_Token: return L"Invalid type for this token.";
case TODO: return L"TODO";
}
return L"Invalid code.";
}

View file

@ -89,7 +89,7 @@ StringArray FormatASS2::GetWriteExtensions() const
///////////////
// Constructor
FormatHandlerASS::FormatHandlerASS(Model &_model,int version)
: model(_model), formatVersion(version)
: FormatHandler(_model), formatVersion(version)
{
}
@ -125,10 +125,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 = model.GetSection(curGroup);
if (prevGroup != curGroup) section = GetSection(curGroup);
if (!section) {
model.AddSection(curGroup);
section = model.GetSection(curGroup);
AddSection(curGroup);
section = GetSection(curGroup);
}
// Skip [] lines
@ -157,9 +157,9 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
sections.Add(L"Graphics");
// Look for remaining sections
size_t totalSections = model.GetSectionCount();
size_t totalSections = GetSectionCount();
for (size_t i=0;i<totalSections;i++) {
String name = model.GetSectionByIndex(i)->GetName();
String name = GetSectionByIndex(i)->GetName();
if (sections.Index(name,false,false) == wxNOT_FOUND) sections.Add(name);
}
@ -167,7 +167,7 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
size_t len = sections.size();
for (size_t i=0;i<len;i++) {
// See if it exists
SectionPtr section = model.GetSection(sections[i]);
SectionPtr section = GetSection(sections[i]);
if (section) {
// Add a spacer
if (i != 0) writer.WriteLineToFile(_T(""));

View file

@ -57,7 +57,6 @@ namespace Gorgonsub {
// Advanced Substation Alpha format handler
class FormatHandlerASS : public FormatHandler {
private:
Model &model;
int formatVersion;
SectionEntryPtr MakeEntry(const String &data,SectionPtr section,int version);
@ -72,46 +71,6 @@ namespace Gorgonsub {
void Save(wxOutputStream &file,const String encoding);
};
// Advanced Substation Alpha format base class
class FormatASSFamily : public Format {
public:
virtual ~FormatASSFamily() {}
bool CanStoreText() const { return true; }
bool CanUseTime() const { return true; }
bool HasStyles() const { return true; }
bool HasMargins() const { return true; }
bool HasActors() const { return true; }
};
// Substation Alpha
class FormatSSA : public FormatASSFamily {
public:
FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,0)); }
String GetName() const { return L"Substation Alpha"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
};
// Advanced Substation Alpha
class FormatASS : public FormatASSFamily {
public:
FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,1)); }
String GetName() const { return L"Advanced Substation Alpha"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
};
// Advanced Substation Alpha 2
class FormatASS2 : public FormatASSFamily {
public:
FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,2)); }
String GetName() const { return L"Advanced Substation Alpha 2"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
};
// Dialogue
class DialogueASS : public SectionEntryDialogue, public SerializeText {
private:
@ -120,7 +79,7 @@ namespace Gorgonsub {
String effect;
String actor;
Time start,end;
array<int,4> margin;
array<short,4> margin;
int layer;
bool isComment;
@ -137,6 +96,7 @@ namespace Gorgonsub {
bool HasTime() const { return true; }
bool HasStyle() const { return true; }
bool HasMargins() const { return true; }
String GetDefaultGroup() const { return L"Events"; }
// Read accessors
const String& GetText() const { return text; }
@ -166,6 +126,7 @@ namespace Gorgonsub {
String name;
String font;
float fontSize;
int formatVersion;
array<Colour,5> colour; // 0 = Primary, 1 = Secondary, 2 = Tertiary, 3 = Outline, 4 = Shadow
array<int,4> margin;
@ -203,6 +164,8 @@ namespace Gorgonsub {
float GetFontSize() const { return fontSize; }
Colour GetColour(int n) const { return colour.at(n); }
int GetMargin(int n) const { return margin.at(n); }
String GetDefaultGroup() const;
};
// Raw line
@ -217,6 +180,50 @@ namespace Gorgonsub {
String GetText() const { return data; }
void SetText(const String &_data) { data = _data; }
String GetDefaultGroup() const { return L"Events"; }
};
// Advanced Substation Alpha format base class
class FormatASSFamily : public Format {
public:
virtual ~FormatASSFamily() {}
bool CanStoreText() const { return true; }
bool CanUseTime() const { return true; }
bool HasStyles() const { return true; }
bool HasMargins() const { return true; }
bool HasActors() const { return true; }
SectionEntryDialoguePtr CreateDialogue() const { return SectionEntryDialoguePtr(new DialogueASS()); }
SectionEntryStylePtr CreateStyle() const { return SectionEntryStylePtr(new StyleASS()); }
};
// Substation Alpha
class FormatSSA : public FormatASSFamily {
public:
FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,0)); }
String GetName() const { return L"Substation Alpha"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
};
// Advanced Substation Alpha
class FormatASS : public FormatASSFamily {
public:
FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,1)); }
String GetName() const { return L"Advanced Substation Alpha"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
};
// Advanced Substation Alpha 2
class FormatASS2 : public FormatASSFamily {
public:
FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,2)); }
String GetName() const { return L"Advanced Substation Alpha 2"; }
StringArray GetReadExtensions() const;
StringArray GetWriteExtensions() const;
};
};

View file

@ -43,7 +43,9 @@ using namespace Gorgonsub;
// Constructors
StyleASS::StyleASS()
{
formatVersion = 1;
}
StyleASS::StyleASS(String data,int version)
{
// Try parsing with all different versions
@ -128,8 +130,11 @@ bool StyleASS::Parse(String data,int version)
relativeTo = 0;
if (version == 2) relativeTo = tkn.GetInt();
// End
// Read it all?
if (tkn.HasMore()) return false;
// Done
formatVersion = version;
return true;
}
@ -226,3 +231,15 @@ String StyleASS::ToText(int version) const
// Done
return final;
}
/////////////////////
// Get default group
String StyleASS::GetDefaultGroup() const
{
switch (formatVersion) {
case 0: return L"V4 Events";
case 1: return L"V4+ Events";
default: return L"V4++ Events";
}
}

View file

@ -58,27 +58,54 @@ void Model::DispatchNotifications(const Notification &notification) const
////////////////////////////
// Processes an action list
void Model::ProcessActionList(const Manipulator &actionList,bool insertInStack)
void Model::ProcessActionList(const ActionList &_actionList,bool insertInStack)
{
// Copy the list
ActionListPtr actions = ActionListPtr(new ActionList(_actionList));
// Inserts the opposite into the undo stack
if (insertInStack) {
undoStack.push_back(CreateAntiManipulator(actionList));
undoStack.push_back(CreateAntiActionList(actions));
redoStack.clear();
}
// Do action
// TODO
// Do actions
std::list<Action>::iterator cur;
for (cur=actions->actions.begin();cur!=actions->actions.end();cur++) {
DoAction(*cur);
}
// Notify listeners
DispatchNotifications(Notification());
}
////////////////////////////////////////////////////////////////////////
// Create an anti-manipulator to undo the actions made by a manipulator
Manipulator Model::CreateAntiManipulator(const Manipulator &src)
/////////////////////
// Execute an action
void Model::DoAction(const Action &action)
{
Manipulator dst(*this,src.actionName);
switch (action.GetType()) {
case ACTION_INSERT: {
// Get the line
SectionEntryPtr entry = static_pointer_cast<SectionEntry>(action.GetData());
// Find the section to insert it on
String sectionName = action.GetSection();
if (sectionName.IsEmpty()) sectionName = entry->GetDefaultGroup();
SectionPtr section = GetSection(sectionName);
// Insert the line
section->AddEntry(entry,action.GetLineNumber());
}
}
}
//////////////////////////////////////////////////////////////////////
// Create an anti-actionlist to undo the actions made by a actionlist
ActionListPtr Model::CreateAntiActionList(const ActionListPtr &src)
{
ActionListPtr dst(new ActionList(*this,src->actionName));
// TODO
return dst;
}
@ -86,10 +113,10 @@ Manipulator Model::CreateAntiManipulator(const Manipulator &src)
//////////////////
// Load subtitles
void Model::Load(wxInputStream &input,const FormatPtr format,const String encoding)
void Model::Load(wxInputStream &input,const FormatPtr _format,const String encoding)
{
// Autodetect format
if (!format) {
if (!_format) {
// TODO
// No format found
@ -97,7 +124,7 @@ void Model::Load(wxInputStream &input,const FormatPtr format,const String encodi
}
// Get handler
FormatHandlerPtr handler = format->GetHandler(*this);
FormatHandlerPtr handler = _format->GetHandler(*this);
if (!handler) throw Exception(Exception::No_Format_Handler);
// Clear the model first
@ -105,19 +132,20 @@ void Model::Load(wxInputStream &input,const FormatPtr format,const String encodi
// Load
handler->Load(input,encoding);
// Set the format
format = _format;
}
//////////////////
// Save subtitles
void Model::Save(wxOutputStream &output,const FormatPtr format,const String encoding)
void Model::Save(wxOutputStream &output,const FormatPtr _format,const String encoding)
{
// Autodetect format
if (!format) {
// Use another format
if (_format && _format != format) {
// TODO
// No format found
throw Exception(Exception::No_Format_Handler);
throw Exception(Exception::TODO);
}
// Get handler
@ -129,26 +157,6 @@ void Model::Save(wxOutputStream &output,const FormatPtr format,const String enco
}
///////////////
// Load a file
void Model::LoadFile(const String filename,const String encoding)
{
const FormatPtr handler = FormatManager::GetFormatFromFilename(filename,true);
wxFileInputStream stream(filename);
Load(stream,handler,encoding);
}
///////////////
// Save a file
void Model::SaveFile(const String filename,const String encoding)
{
const FormatPtr handler = FormatManager::GetFormatFromFilename(filename,true);
wxFileOutputStream stream(filename);
Save(stream,handler,encoding);
}
/////////////////////////
// Inserts a new section
void Model::AddSection(String name)

View file

@ -48,9 +48,10 @@ Section::Section(String _name)
///////////////////
// Append an entry
void Section::AddEntry(SectionEntryPtr entry)
void Section::AddEntry(SectionEntryPtr entry,int pos)
{
entries.push_back(entry);
if (pos == -1) entries.push_back(entry);
else entries.insert(entries.begin()+pos,entry);
}
void Section::RemoveEntryByIndex(size_t index)

View file

@ -52,20 +52,29 @@ int main () {
// Subtitles model
Model subs;
Controller control(subs);
// Load subtitles
cout << "Loading file... ";
subs.LoadFile(L"subs_in.ass",L"UTF-8");
control.LoadFile(L"subs_in.ass",L"UTF-8");
cout << "Done.\n";
// Modify subtitles
cout << "Modifying file...";
// TODO
// Create line to be inserted
cout << "Creating data... ";
SectionEntryDialoguePtr line = control.CreateDialogue();
line->SetText(L"Hi, testing insertion of lines!");
cout << "Done.\n";
// Create action list
cout << "Processing actions... ";
ActionListPtr actions = control.CreateActionList(L"Insert line");
actions->InsertLine(line,2);
actions->Finish();
cout << "Done.\n";
// Save subtitles
cout << "Saving file... ";
subs.SaveFile(L"subs_out.ass",L"UTF-8");
control.SaveFile(L"subs_out.ass",L"UTF-8");
cout << "Done.\n";
}