forked from mia/Aegisub
Gorgonsub is now capable of doing some simple manipulation (i.e. line insertion).
Originally committed to SVN as r2048.
This commit is contained in:
parent
bb425f8a86
commit
b073b7d28d
21 changed files with 404 additions and 145 deletions
|
@ -160,6 +160,10 @@
|
||||||
RelativePath=".\include\aegilib\action.h"
|
RelativePath=".\include\aegilib\action.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\aegilib\actionlist.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\aegilib\colour.h"
|
RelativePath=".\include\aegilib\colour.h"
|
||||||
>
|
>
|
||||||
|
@ -196,10 +200,6 @@
|
||||||
RelativePath=".\include\aegilib\gorgontime.h"
|
RelativePath=".\include\aegilib\gorgontime.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\include\aegilib\manipulator.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\aegilib\model.h"
|
RelativePath=".\include\aegilib\model.h"
|
||||||
>
|
>
|
||||||
|
@ -253,7 +253,11 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\manipulator.cpp"
|
RelativePath=".\src\actionlist.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\controller.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "gorgonstring.h"
|
||||||
|
|
||||||
namespace Gorgonsub {
|
namespace Gorgonsub {
|
||||||
// The different types of actions available
|
// The different types of actions available
|
||||||
|
@ -48,14 +49,16 @@ namespace Gorgonsub {
|
||||||
private:
|
private:
|
||||||
ActionType type;
|
ActionType type;
|
||||||
shared_ptr<void> data;
|
shared_ptr<void> data;
|
||||||
|
String section;
|
||||||
int par1;
|
int par1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Action();
|
Action();
|
||||||
Action(ActionType type,shared_ptr<void> data,int par1);
|
Action(ActionType type,shared_ptr<void> data,const String §ion,int par1);
|
||||||
|
|
||||||
ActionType GetType() { return type; }
|
ActionType GetType() const { return type; }
|
||||||
shared_ptr<void> GetData() { return data; }
|
shared_ptr<void> GetData() const { return data; }
|
||||||
int GetLineNumber() { return par1; }
|
int GetLineNumber() const { return par1; }
|
||||||
|
String GetSection() const { return section; }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,13 +37,17 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "gorgonstring.h"
|
#include "gorgonstring.h"
|
||||||
|
#include "section_entry.h"
|
||||||
|
|
||||||
namespace Gorgonsub {
|
namespace Gorgonsub {
|
||||||
|
|
||||||
// Manipulator class
|
// Prototypes
|
||||||
class Manipulator {
|
class Controller;
|
||||||
|
|
||||||
|
// ActionList class
|
||||||
|
class ActionList {
|
||||||
friend class Model;
|
friend class Model;
|
||||||
friend class std::list<Manipulator>;
|
friend class Controller;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String actionName;
|
String actionName;
|
||||||
|
@ -51,14 +55,18 @@ namespace Gorgonsub {
|
||||||
std::list<Action> actions;
|
std::list<Action> actions;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
Manipulator();
|
ActionList();
|
||||||
|
ActionList(Model &model,const String actionName);
|
||||||
|
void Start(const String actionName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Manipulator(Model &model,String actionName);
|
~ActionList();
|
||||||
~Manipulator();
|
|
||||||
|
|
||||||
void AddAction(const Action &action);
|
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;
|
||||||
|
|
||||||
};
|
};
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
|
@ -46,12 +46,13 @@ namespace Gorgonsub {
|
||||||
enum ExceptionList {
|
enum ExceptionList {
|
||||||
Unknown,
|
Unknown,
|
||||||
No_Format_Handler,
|
No_Format_Handler,
|
||||||
Invalid_Manipulator,
|
Invalid_ActionList,
|
||||||
Section_Already_Exists,
|
Section_Already_Exists,
|
||||||
Unknown_Format,
|
Unknown_Format,
|
||||||
Parse_Error,
|
Parse_Error,
|
||||||
Unsupported_Format_Feature,
|
Unsupported_Format_Feature,
|
||||||
Invalid_Token
|
Invalid_Token,
|
||||||
|
TODO
|
||||||
};
|
};
|
||||||
|
|
||||||
Exception(ExceptionList code);
|
Exception(ExceptionList code);
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gorgonstring.h"
|
#include "gorgonstring.h"
|
||||||
#include "tr1.h"
|
#include "tr1.h"
|
||||||
|
#include "section_entry.h"
|
||||||
|
|
||||||
namespace Gorgonsub {
|
namespace Gorgonsub {
|
||||||
// Prototypes
|
// Prototypes
|
||||||
|
@ -65,6 +66,9 @@ namespace Gorgonsub {
|
||||||
|
|
||||||
virtual int GetTimingPrecision() const { return 10; } // In milliseconds
|
virtual int GetTimingPrecision() const { return 10; } // In milliseconds
|
||||||
virtual int GetMaxTime() const { return 36000000-10; } // In milliseconds, default 9h 59min 59.99s
|
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;
|
typedef shared_ptr<Format> FormatPtr;
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,29 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gorgonstring.h"
|
#include "gorgonstring.h"
|
||||||
|
#include "model.h"
|
||||||
#include "tr1.h"
|
#include "tr1.h"
|
||||||
|
|
||||||
namespace Gorgonsub {
|
namespace Gorgonsub {
|
||||||
|
|
||||||
// Format handler interface
|
// Format handler interface
|
||||||
class FormatHandler {
|
class FormatHandler {
|
||||||
|
private:
|
||||||
|
Model &model;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~FormatHandler() {}
|
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:
|
public:
|
||||||
|
FormatHandler(Model &_model) : model(_model) {}
|
||||||
|
|
||||||
virtual void Load(wxInputStream &file,const String encoding) = 0;
|
virtual void Load(wxInputStream &file,const String encoding) = 0;
|
||||||
virtual void Save(wxOutputStream &file,const String encoding) = 0;
|
virtual void Save(wxOutputStream &file,const String encoding) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include "format_handler.h"
|
#include "format_handler.h"
|
||||||
#include "format_manager.h"
|
#include "format_manager.h"
|
||||||
#include "manipulator.h"
|
#include "actionlist.h"
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
#include "section_entry_dialogue.h"
|
#include "section_entry_dialogue.h"
|
||||||
#include "section_entry_style.h"
|
#include "section_entry_style.h"
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/wfstream.h>
|
#include <wx/wfstream.h>
|
||||||
#include "manipulator.h"
|
#include "actionlist.h"
|
||||||
#include "section.h"
|
#include "section.h"
|
||||||
|
|
||||||
namespace Gorgonsub {
|
namespace Gorgonsub {
|
||||||
|
@ -51,9 +51,12 @@ namespace Gorgonsub {
|
||||||
// Model class
|
// Model class
|
||||||
// Stores the subtitle data
|
// Stores the subtitle data
|
||||||
class Model {
|
class Model {
|
||||||
friend class Manipulator;
|
friend class FormatHandler;
|
||||||
|
friend class ActionList;
|
||||||
|
friend class Controller;
|
||||||
|
|
||||||
typedef std::list<ViewPtr> ViewList;
|
typedef std::list<ViewPtr> ViewList;
|
||||||
typedef std::list<const Manipulator> ActionStack;
|
typedef std::list<ActionListPtr> ActionStack;
|
||||||
typedef shared_ptr<Format> FormatPtr;
|
typedef shared_ptr<Format> FormatPtr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -62,30 +65,31 @@ namespace Gorgonsub {
|
||||||
ActionStack redoStack;
|
ActionStack redoStack;
|
||||||
ViewList listeners;
|
ViewList listeners;
|
||||||
bool readOnly;
|
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 ¬ification) const;
|
void DispatchNotifications(const Notification ¬ification) 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);
|
void AddSection(String name);
|
||||||
SectionPtr GetSection(String name) const;
|
SectionPtr GetSection(String name) const;
|
||||||
SectionPtr GetSectionByIndex(size_t index) const;
|
SectionPtr GetSectionByIndex(size_t index) const;
|
||||||
size_t GetSectionCount() const;
|
size_t GetSectionCount() const;
|
||||||
|
|
||||||
bool CanUndo(const String owner=L"") const;
|
void Clear();
|
||||||
bool CanRedo(const String owner=L"") const;
|
void Load(wxInputStream &input,const FormatPtr format=FormatPtr(),const String encoding=L"");
|
||||||
bool Undo(const String owner=L"");
|
void Save(wxOutputStream &output,const FormatPtr format=FormatPtr(),const String encoding=L"UTF-8");
|
||||||
bool Redo(const String owner=L"");
|
|
||||||
|
public:
|
||||||
|
const FormatPtr GetFormat() const { return format; }
|
||||||
|
void AddListener(ViewPtr listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace Gorgonsub {
|
||||||
String GetPropertyName(size_t index) const;
|
String GetPropertyName(size_t index) const;
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
void AddEntry(SectionEntryPtr entry);
|
void AddEntry(SectionEntryPtr entry,int pos=-1);
|
||||||
void RemoveEntryByIndex(size_t index);
|
void RemoveEntryByIndex(size_t index);
|
||||||
void RemoveEntry(SectionEntryPtr entry);
|
void RemoveEntry(SectionEntryPtr entry);
|
||||||
SectionEntryConstPtr GetEntry(size_t index) const;
|
SectionEntryConstPtr GetEntry(size_t index) const;
|
||||||
|
|
|
@ -76,6 +76,8 @@ namespace Gorgonsub {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual SectionEntryType GetType() const =0;
|
virtual SectionEntryType GetType() const =0;
|
||||||
|
virtual String GetDefaultGroup() const =0;
|
||||||
|
|
||||||
static const SectionEntryPlainPtr GetAsPlain(const SectionEntryPtr &ptr);
|
static const SectionEntryPlainPtr GetAsPlain(const SectionEntryPtr &ptr);
|
||||||
static const SectionEntryDialoguePtr GetAsDialogue(const SectionEntryPtr &ptr);
|
static const SectionEntryDialoguePtr GetAsDialogue(const SectionEntryPtr &ptr);
|
||||||
static const SectionEntryDialogueConstPtr GetAsDialogue(const SectionEntryConstPtr &ptr);
|
static const SectionEntryDialogueConstPtr GetAsDialogue(const SectionEntryConstPtr &ptr);
|
||||||
|
|
|
@ -46,9 +46,10 @@ Action::Action()
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Initialization constructor
|
// 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;
|
type = _type;
|
||||||
data = _data;
|
data = _data;
|
||||||
par1 = _par1;
|
par1 = _par1;
|
||||||
|
section = _section;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,34 +39,42 @@ using namespace Gorgonsub;
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
Manipulator::Manipulator(Model &_model,String _actionName)
|
ActionList::ActionList(Model &_model,String _actionName)
|
||||||
: model(_model)
|
: model(_model)
|
||||||
{
|
{
|
||||||
actionName = _actionName;
|
Start(_actionName);
|
||||||
valid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// Destructor
|
// Destructor
|
||||||
Manipulator::~Manipulator()
|
ActionList::~ActionList()
|
||||||
{
|
{
|
||||||
Flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Add an action to the queue
|
// 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);
|
actions.push_back(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
/////////////////////////////
|
||||||
// Flush the queue to the model
|
// Starts performing actions
|
||||||
void Manipulator::Flush()
|
void ActionList::Start(const String name)
|
||||||
|
{
|
||||||
|
if (valid) Finish();
|
||||||
|
actionName = name;
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// Ends the action list
|
||||||
|
void ActionList::Finish()
|
||||||
{
|
{
|
||||||
if (valid) {
|
if (valid) {
|
||||||
model.ProcessActionList(*this,false);
|
model.ProcessActionList(*this,false);
|
||||||
|
@ -74,3 +82,12 @@ void Manipulator::Flush()
|
||||||
valid = false;
|
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);
|
||||||
|
}
|
93
aegilib/src/controller.cpp
Normal file
93
aegilib/src/controller.cpp
Normal 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();
|
||||||
|
}
|
|
@ -53,12 +53,13 @@ String Exception::GetMessage(int code)
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case Unknown: return L"Unknown.";
|
case Unknown: return L"Unknown.";
|
||||||
case No_Format_Handler: return L"Could not find a suitable format handler.";
|
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 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 Unknown_Format: return L"The specified file format is unknown.";
|
||||||
case Parse_Error: return L"Parse error.";
|
case Parse_Error: return L"Parse error.";
|
||||||
case Unsupported_Format_Feature: return L"This feature is not supported by this format.";
|
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 Invalid_Token: return L"Invalid type for this token.";
|
||||||
|
case TODO: return L"TODO";
|
||||||
}
|
}
|
||||||
return L"Invalid code.";
|
return L"Invalid code.";
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ StringArray FormatASS2::GetWriteExtensions() const
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
FormatHandlerASS::FormatHandlerASS(Model &_model,int version)
|
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);
|
ProcessGroup(cur,curGroup,version);
|
||||||
|
|
||||||
// Insert group if it doesn't already exist
|
// Insert group if it doesn't already exist
|
||||||
if (prevGroup != curGroup) section = model.GetSection(curGroup);
|
if (prevGroup != curGroup) section = GetSection(curGroup);
|
||||||
if (!section) {
|
if (!section) {
|
||||||
model.AddSection(curGroup);
|
AddSection(curGroup);
|
||||||
section = model.GetSection(curGroup);
|
section = GetSection(curGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip [] lines
|
// Skip [] lines
|
||||||
|
@ -157,9 +157,9 @@ void FormatHandlerASS::Save(wxOutputStream &file,const String encoding)
|
||||||
sections.Add(L"Graphics");
|
sections.Add(L"Graphics");
|
||||||
|
|
||||||
// Look for remaining sections
|
// Look for remaining sections
|
||||||
size_t totalSections = model.GetSectionCount();
|
size_t totalSections = GetSectionCount();
|
||||||
for (size_t i=0;i<totalSections;i++) {
|
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);
|
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();
|
size_t len = sections.size();
|
||||||
for (size_t i=0;i<len;i++) {
|
for (size_t i=0;i<len;i++) {
|
||||||
// See if it exists
|
// See if it exists
|
||||||
SectionPtr section = model.GetSection(sections[i]);
|
SectionPtr section = GetSection(sections[i]);
|
||||||
if (section) {
|
if (section) {
|
||||||
// Add a spacer
|
// Add a spacer
|
||||||
if (i != 0) writer.WriteLineToFile(_T(""));
|
if (i != 0) writer.WriteLineToFile(_T(""));
|
||||||
|
|
|
@ -57,7 +57,6 @@ namespace Gorgonsub {
|
||||||
// Advanced Substation Alpha format handler
|
// Advanced Substation Alpha format handler
|
||||||
class FormatHandlerASS : public FormatHandler {
|
class FormatHandlerASS : public FormatHandler {
|
||||||
private:
|
private:
|
||||||
Model &model;
|
|
||||||
int formatVersion;
|
int formatVersion;
|
||||||
|
|
||||||
SectionEntryPtr MakeEntry(const String &data,SectionPtr section,int version);
|
SectionEntryPtr MakeEntry(const String &data,SectionPtr section,int version);
|
||||||
|
@ -72,46 +71,6 @@ namespace Gorgonsub {
|
||||||
void Save(wxOutputStream &file,const String encoding);
|
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
|
// Dialogue
|
||||||
class DialogueASS : public SectionEntryDialogue, public SerializeText {
|
class DialogueASS : public SectionEntryDialogue, public SerializeText {
|
||||||
private:
|
private:
|
||||||
|
@ -120,7 +79,7 @@ namespace Gorgonsub {
|
||||||
String effect;
|
String effect;
|
||||||
String actor;
|
String actor;
|
||||||
Time start,end;
|
Time start,end;
|
||||||
array<int,4> margin;
|
array<short,4> margin;
|
||||||
int layer;
|
int layer;
|
||||||
bool isComment;
|
bool isComment;
|
||||||
|
|
||||||
|
@ -137,6 +96,7 @@ namespace Gorgonsub {
|
||||||
bool HasTime() const { return true; }
|
bool HasTime() const { return true; }
|
||||||
bool HasStyle() const { return true; }
|
bool HasStyle() const { return true; }
|
||||||
bool HasMargins() const { return true; }
|
bool HasMargins() const { return true; }
|
||||||
|
String GetDefaultGroup() const { return L"Events"; }
|
||||||
|
|
||||||
// Read accessors
|
// Read accessors
|
||||||
const String& GetText() const { return text; }
|
const String& GetText() const { return text; }
|
||||||
|
@ -166,6 +126,7 @@ namespace Gorgonsub {
|
||||||
String name;
|
String name;
|
||||||
String font;
|
String font;
|
||||||
float fontSize;
|
float fontSize;
|
||||||
|
int formatVersion;
|
||||||
|
|
||||||
array<Colour,5> colour; // 0 = Primary, 1 = Secondary, 2 = Tertiary, 3 = Outline, 4 = Shadow
|
array<Colour,5> colour; // 0 = Primary, 1 = Secondary, 2 = Tertiary, 3 = Outline, 4 = Shadow
|
||||||
array<int,4> margin;
|
array<int,4> margin;
|
||||||
|
@ -203,6 +164,8 @@ namespace Gorgonsub {
|
||||||
float GetFontSize() const { return fontSize; }
|
float GetFontSize() const { return fontSize; }
|
||||||
Colour GetColour(int n) const { return colour.at(n); }
|
Colour GetColour(int n) const { return colour.at(n); }
|
||||||
int GetMargin(int n) const { return margin.at(n); }
|
int GetMargin(int n) const { return margin.at(n); }
|
||||||
|
|
||||||
|
String GetDefaultGroup() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Raw line
|
// Raw line
|
||||||
|
@ -217,6 +180,50 @@ namespace Gorgonsub {
|
||||||
|
|
||||||
String GetText() const { return data; }
|
String GetText() const { return data; }
|
||||||
void SetText(const String &_data) { data = _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;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,9 @@ using namespace Gorgonsub;
|
||||||
// Constructors
|
// Constructors
|
||||||
StyleASS::StyleASS()
|
StyleASS::StyleASS()
|
||||||
{
|
{
|
||||||
|
formatVersion = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleASS::StyleASS(String data,int version)
|
StyleASS::StyleASS(String data,int version)
|
||||||
{
|
{
|
||||||
// Try parsing with all different versions
|
// Try parsing with all different versions
|
||||||
|
@ -128,8 +130,11 @@ bool StyleASS::Parse(String data,int version)
|
||||||
relativeTo = 0;
|
relativeTo = 0;
|
||||||
if (version == 2) relativeTo = tkn.GetInt();
|
if (version == 2) relativeTo = tkn.GetInt();
|
||||||
|
|
||||||
// End
|
// Read it all?
|
||||||
if (tkn.HasMore()) return false;
|
if (tkn.HasMore()) return false;
|
||||||
|
|
||||||
|
// Done
|
||||||
|
formatVersion = version;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,3 +231,15 @@ String StyleASS::ToText(int version) const
|
||||||
// Done
|
// Done
|
||||||
return final;
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -58,27 +58,54 @@ void Model::DispatchNotifications(const Notification ¬ification) const
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
// Processes an action list
|
// 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
|
// Inserts the opposite into the undo stack
|
||||||
if (insertInStack) {
|
if (insertInStack) {
|
||||||
undoStack.push_back(CreateAntiManipulator(actionList));
|
undoStack.push_back(CreateAntiActionList(actions));
|
||||||
redoStack.clear();
|
redoStack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do action
|
// Do actions
|
||||||
// TODO
|
std::list<Action>::iterator cur;
|
||||||
|
for (cur=actions->actions.begin();cur!=actions->actions.end();cur++) {
|
||||||
|
DoAction(*cur);
|
||||||
|
}
|
||||||
|
|
||||||
// Notify listeners
|
// Notify listeners
|
||||||
DispatchNotifications(Notification());
|
DispatchNotifications(Notification());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
/////////////////////
|
||||||
// Create an anti-manipulator to undo the actions made by a manipulator
|
// Execute an action
|
||||||
Manipulator Model::CreateAntiManipulator(const Manipulator &src)
|
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
|
// TODO
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
@ -86,10 +113,10 @@ Manipulator Model::CreateAntiManipulator(const Manipulator &src)
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// Load subtitles
|
// 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
|
// Autodetect format
|
||||||
if (!format) {
|
if (!_format) {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
// No format found
|
// No format found
|
||||||
|
@ -97,7 +124,7 @@ void Model::Load(wxInputStream &input,const FormatPtr format,const String encodi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get handler
|
// Get handler
|
||||||
FormatHandlerPtr handler = format->GetHandler(*this);
|
FormatHandlerPtr handler = _format->GetHandler(*this);
|
||||||
if (!handler) throw Exception(Exception::No_Format_Handler);
|
if (!handler) throw Exception(Exception::No_Format_Handler);
|
||||||
|
|
||||||
// Clear the model first
|
// Clear the model first
|
||||||
|
@ -105,19 +132,20 @@ void Model::Load(wxInputStream &input,const FormatPtr format,const String encodi
|
||||||
|
|
||||||
// Load
|
// Load
|
||||||
handler->Load(input,encoding);
|
handler->Load(input,encoding);
|
||||||
|
|
||||||
|
// Set the format
|
||||||
|
format = _format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// Save subtitles
|
// 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
|
// Use another format
|
||||||
if (!format) {
|
if (_format && _format != format) {
|
||||||
// TODO
|
// TODO
|
||||||
|
throw Exception(Exception::TODO);
|
||||||
// No format found
|
|
||||||
throw Exception(Exception::No_Format_Handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get handler
|
// 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
|
// Inserts a new section
|
||||||
void Model::AddSection(String name)
|
void Model::AddSection(String name)
|
||||||
|
|
|
@ -48,9 +48,10 @@ Section::Section(String _name)
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// Append an entry
|
// 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)
|
void Section::RemoveEntryByIndex(size_t index)
|
||||||
|
|
|
@ -52,20 +52,29 @@ int main () {
|
||||||
|
|
||||||
// Subtitles model
|
// Subtitles model
|
||||||
Model subs;
|
Model subs;
|
||||||
|
Controller control(subs);
|
||||||
|
|
||||||
// Load subtitles
|
// Load subtitles
|
||||||
cout << "Loading file... ";
|
cout << "Loading file... ";
|
||||||
subs.LoadFile(L"subs_in.ass",L"UTF-8");
|
control.LoadFile(L"subs_in.ass",L"UTF-8");
|
||||||
cout << "Done.\n";
|
cout << "Done.\n";
|
||||||
|
|
||||||
// Modify subtitles
|
// Create line to be inserted
|
||||||
cout << "Modifying file...";
|
cout << "Creating data... ";
|
||||||
// TODO
|
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";
|
cout << "Done.\n";
|
||||||
|
|
||||||
// Save subtitles
|
// Save subtitles
|
||||||
cout << "Saving file... ";
|
cout << "Saving file... ";
|
||||||
subs.SaveFile(L"subs_out.ass",L"UTF-8");
|
control.SaveFile(L"subs_out.ass",L"UTF-8");
|
||||||
cout << "Done.\n";
|
cout << "Done.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue