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"
|
||||
>
|
||||
</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
|
||||
|
|
|
@ -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 §ion,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; }
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
|
@ -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 {
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 Manipulator &actionList,bool insertInStack);
|
||||
Manipulator CreateAntiManipulator(const Manipulator &manipulator);
|
||||
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 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);
|
||||
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);
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
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) {
|
||||
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.";
|
||||
}
|
||||
|
|
|
@ -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(""));
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,27 +58,54 @@ void Model::DispatchNotifications(const Notification ¬ification) 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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue