mirror of https://github.com/odrling/Aegisub
Redesign export filters to not be static singletons, removing the need to jump through hoops to avoid static initialization order issues
Originally committed to SVN as r5258.
This commit is contained in:
parent
83a461ca63
commit
af92002d8c
|
@ -39,178 +39,53 @@
|
||||||
#include "ass_export_filter.h"
|
#include "ass_export_filter.h"
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
|
|
||||||
|
AssExportFilter::AssExportFilter(wxString const& name, wxString const& description, int priority)
|
||||||
/// @brief Constructor
|
: name(name)
|
||||||
///
|
, priority(priority)
|
||||||
AssExportFilter::AssExportFilter() {
|
, autoExporter(false)
|
||||||
hidden = false;
|
, hidden(false)
|
||||||
autoExporter = false;
|
, description(description)
|
||||||
initialized = false;
|
{
|
||||||
FilterList *fil = AssExportFilterChain::GetUnpreparedFilterList();
|
|
||||||
fil->push_back(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssExportFilterChain::Register(AssExportFilter *filter) {
|
||||||
|
|
||||||
/// @brief Destructor
|
|
||||||
///
|
|
||||||
AssExportFilter::~AssExportFilter() {
|
|
||||||
try {
|
|
||||||
Unregister();
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
// Ignore error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Register
|
|
||||||
/// @param name
|
|
||||||
/// @param priority
|
|
||||||
///
|
|
||||||
void AssExportFilter::Register (wxString name,int priority) {
|
|
||||||
// Check if it's registered
|
|
||||||
// Changed this to an assert, since this kind of error should really only happen during dev. -jfs
|
|
||||||
// (Actually the list of regged filters should rather be looped through and check that this object isn't in.)
|
|
||||||
assert(RegisterName == _T(""));
|
|
||||||
|
|
||||||
// Remove pipes from name
|
// Remove pipes from name
|
||||||
name.Replace(_T("|"),_T(""));
|
filter->name.Replace("|", "");
|
||||||
|
|
||||||
|
FilterList::iterator begin = GetFilterList()->begin();
|
||||||
|
FilterList::iterator end = GetFilterList()->end();
|
||||||
|
|
||||||
int filter_copy = 0;
|
int filter_copy = 0;
|
||||||
wxString tmpnam;
|
wxString tmpnam = filter->name;
|
||||||
if (filter_copy == 0) {
|
if (false) {
|
||||||
tmpnam = name;
|
|
||||||
} else {
|
|
||||||
try_new_name:
|
try_new_name:
|
||||||
tmpnam = wxString::Format(_T("%s (%d)"), name.c_str(), filter_copy);
|
tmpnam = wxString::Format("%s (%d)", filter->name, filter_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if name exists
|
// Check if name exists
|
||||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
|
||||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||||
if ((*cur)->RegisterName == tmpnam) {
|
if ((*cur)->name == tmpnam) {
|
||||||
// Instead of just failing and making a big noise about it, let multiple filters share name, but append something to the later arrivals -jfs
|
// Instead of just failing and making a big noise about it, let multiple filters share name, but append something to the later arrivals -jfs
|
||||||
filter_copy++;
|
filter_copy++;
|
||||||
goto try_new_name;
|
goto try_new_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set name
|
filter->name = tmpnam;
|
||||||
RegisterName = tmpnam;
|
|
||||||
Priority = priority;
|
|
||||||
|
|
||||||
// Look for place to insert
|
// Look for place to insert
|
||||||
bool inserted = false;
|
while (begin != end && (*begin)->priority >= filter->priority) ++begin;
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
GetFilterList()->insert(begin, filter);
|
||||||
if ((*cur)->Priority < Priority) {
|
|
||||||
AssExportFilterChain::GetFilterList()->insert(cur,this);
|
|
||||||
inserted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!inserted) AssExportFilterChain::GetFilterList()->push_back(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssExportFilterChain::Unregister(AssExportFilter *filter) {
|
||||||
|
if (find(GetFilterList()->begin(), GetFilterList()->end(), filter) == GetFilterList()->end())
|
||||||
|
throw wxString::Format("Unregister export filter: name \"%s\" is not registered.", filter->name);
|
||||||
|
|
||||||
|
GetFilterList()->remove(filter);
|
||||||
/// @brief Unregister
|
|
||||||
///
|
|
||||||
void AssExportFilter::Unregister () {
|
|
||||||
// Check if it's registered
|
|
||||||
if (!IsRegistered()) throw wxString::Format(_T("Unregister export filter: name \"%s\" is not registered."), RegisterName.c_str());
|
|
||||||
|
|
||||||
// Unregister
|
|
||||||
RegisterName = _T("");
|
|
||||||
AssExportFilterChain::GetFilterList()->remove(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Checks if it's registered
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
bool AssExportFilter::IsRegistered() {
|
|
||||||
// Check name
|
|
||||||
if (RegisterName.IsEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check list
|
|
||||||
bool found = false;
|
|
||||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
|
||||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
|
||||||
if ((*cur) == this) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get sizer
|
|
||||||
/// @param parent
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
wxWindow *AssExportFilter::GetConfigDialogWindow(wxWindow *parent) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Config dialog OK
|
|
||||||
/// @param IsDefault
|
|
||||||
///
|
|
||||||
void AssExportFilter::LoadSettings(bool IsDefault) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Description reader
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString& AssExportFilter::GetDescription() const {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
std::auto_ptr<AssExportFilterChain> AssExportFilterChain::instance;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get list
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
FilterList *AssExportFilterChain::GetFilterList() {
|
FilterList *AssExportFilterChain::GetFilterList() {
|
||||||
if (!instance.get()) instance.reset(new AssExportFilterChain());
|
static FilterList instance;
|
||||||
return &(instance->Filters);
|
return &instance;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get unprepared list
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
FilterList *AssExportFilterChain::GetUnpreparedFilterList() {
|
|
||||||
if (!instance.get()) instance.reset(new AssExportFilterChain());
|
|
||||||
return &(instance->Unprepared);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Prepare filters
|
|
||||||
///
|
|
||||||
void AssExportFilterChain::PrepareFilters() {
|
|
||||||
if (!instance.get()) instance.reset(new AssExportFilterChain());
|
|
||||||
for (FilterList::iterator cur=instance->Unprepared.begin();cur!=instance->Unprepared.end();cur++) {
|
|
||||||
(*cur)->Init();
|
|
||||||
}
|
|
||||||
instance->Unprepared.clear();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,24 +58,19 @@ typedef std::list<AssExportFilter*> FilterList;
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class AssExportFilterChain {
|
class AssExportFilterChain {
|
||||||
friend class AssExportFilter;
|
|
||||||
friend class AssExporter;
|
friend class AssExporter;
|
||||||
|
|
||||||
private:
|
/// The list of registered filters
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
FilterList Filters;
|
FilterList Filters;
|
||||||
|
|
||||||
/// DOCME
|
/// Get the singleton instance
|
||||||
FilterList Unprepared;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static std::auto_ptr<AssExportFilterChain> instance;
|
|
||||||
static FilterList *GetFilterList();
|
static FilterList *GetFilterList();
|
||||||
static FilterList *GetUnpreparedFilterList();
|
AssExportFilterChain() { }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void PrepareFilters();
|
/// Register an export filter
|
||||||
|
static void Register(AssExportFilter *filter);
|
||||||
|
/// Unregister an export filter; must have been registered
|
||||||
|
static void Unregister(AssExportFilter *filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
|
@ -87,41 +82,33 @@ class AssExportFilter {
|
||||||
friend class AssExporter;
|
friend class AssExporter;
|
||||||
friend class AssExportFilterChain;
|
friend class AssExportFilterChain;
|
||||||
|
|
||||||
private:
|
/// This filter's name
|
||||||
|
wxString name;
|
||||||
|
|
||||||
/// DOCME
|
/// Higher priority = run earlier
|
||||||
wxString RegisterName;
|
int priority;
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
int Priority;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// Should this filter be used when sending subtitles to the subtitle provider
|
||||||
/// DOCME
|
|
||||||
bool autoExporter;
|
bool autoExporter;
|
||||||
|
|
||||||
/// DOCME
|
/// Should this filter be hidden from the user
|
||||||
bool hidden;
|
bool hidden;
|
||||||
|
|
||||||
/// DOCME
|
/// User-visible description of this filter
|
||||||
bool initialized;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxString description;
|
wxString description;
|
||||||
|
|
||||||
void Register(wxString name,int priority=0); // Register the filter with specific name. Higher priority filters get the file to process first.
|
|
||||||
void Unregister(); // Unregister the filter instance
|
|
||||||
bool IsRegistered(); // Is this instance registered as a filter?
|
|
||||||
virtual void Init()=0; // Tell it to initialize itself
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AssExportFilter();
|
AssExportFilter(wxString const& name, wxString const& description, int priority = 0);
|
||||||
virtual ~AssExportFilter();
|
virtual ~AssExportFilter() { };
|
||||||
|
|
||||||
const wxString& GetDescription() const;
|
const wxString& GetDescription() const { return description; }
|
||||||
|
|
||||||
virtual void ProcessSubs(AssFile *subs, wxWindow *export_dialog=0)=0; // Process subtitles - this function must be overriden.
|
/// Process subtitles
|
||||||
virtual wxWindow *GetConfigDialogWindow(wxWindow *parent); // Draw setup controls - this function may optionally be overridden.
|
virtual void ProcessSubs(AssFile *subs, wxWindow *export_dialog=0)=0;
|
||||||
virtual void LoadSettings(bool IsDefault); // Config dialog is done - extract data now.
|
/// Draw setup controls
|
||||||
|
virtual wxWindow *GetConfigDialogWindow(wxWindow *parent) { return 0; }
|
||||||
|
/// Config dialog is done - extract data now.
|
||||||
|
virtual void LoadSettings(bool IsDefault) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -67,13 +67,13 @@ void AssExporter::DrawSettings(wxWindow *parent,wxSizer *AddTo) {
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||||
// Make sure to construct static box sizer first, so it won't overlap
|
// Make sure to construct static box sizer first, so it won't overlap
|
||||||
// the controls on wxMac.
|
// the controls on wxMac.
|
||||||
box = new wxStaticBoxSizer(wxVERTICAL,parent,(*cur)->RegisterName);
|
box = new wxStaticBoxSizer(wxVERTICAL,parent,(*cur)->name);
|
||||||
window = (*cur)->GetConfigDialogWindow(parent);
|
window = (*cur)->GetConfigDialogWindow(parent);
|
||||||
if (window) {
|
if (window) {
|
||||||
box->Add(window,0,wxEXPAND,0);
|
box->Add(window,0,wxEXPAND,0);
|
||||||
AddTo->Add(box,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
|
AddTo->Add(box,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
|
||||||
AddTo->Show(box,false);
|
AddTo->Show(box,false);
|
||||||
Sizers[(*cur)->RegisterName] = box;
|
Sizers[(*cur)->name] = box;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delete box;
|
delete box;
|
||||||
|
@ -90,13 +90,14 @@ void AssExporter::AddFilter(wxString name) {
|
||||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||||
if ((*cur)->RegisterName == name) {
|
if ((*cur)->name == name) {
|
||||||
filter = *cur;
|
filter = *cur;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
if (!filter) throw wxString::Format(_T("Filter not found: %s"), name.c_str());
|
if (!filter) throw wxString::Format("Filter not found: %s", name.c_str());
|
||||||
|
|
||||||
// Add to list
|
// Add to list
|
||||||
Filters.push_back(filter);
|
Filters.push_back(filter);
|
||||||
|
@ -122,7 +123,7 @@ wxArrayString AssExporter::GetAllFilterNames() {
|
||||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||||
if (!(*cur)->hidden) names.Add((*cur)->RegisterName);
|
if (!(*cur)->hidden) names.Add((*cur)->name);
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
@ -172,9 +173,9 @@ wxString AssExporter::GetDescription(wxString name) {
|
||||||
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
|
||||||
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
|
||||||
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
for (FilterList::iterator cur=begin;cur!=end;cur++) {
|
||||||
if ((*cur)->RegisterName == name) {
|
if ((*cur)->name == name) {
|
||||||
return (*cur)->GetDescription();
|
return (*cur)->GetDescription();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw wxString::Format(_T("Filter not found: %s"), name.c_str());
|
throw wxString::Format("Filter not found: %s", name.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,11 +291,10 @@ namespace Automation4 {
|
||||||
///
|
///
|
||||||
FeatureFilter::FeatureFilter(const wxString &_name, const wxString &_description, int _priority)
|
FeatureFilter::FeatureFilter(const wxString &_name, const wxString &_description, int _priority)
|
||||||
: Feature(SCRIPTFEATURE_FILTER, _name)
|
: Feature(SCRIPTFEATURE_FILTER, _name)
|
||||||
, AssExportFilter()
|
, AssExportFilter(_name, _description, _priority)
|
||||||
, config_dialog(0)
|
, config_dialog(0)
|
||||||
{
|
{
|
||||||
description = _description; // from AssExportFilter
|
AssExportFilterChain::Register(this);
|
||||||
Register(_name, _priority);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,7 +302,7 @@ namespace Automation4 {
|
||||||
///
|
///
|
||||||
FeatureFilter::~FeatureFilter()
|
FeatureFilter::~FeatureFilter()
|
||||||
{
|
{
|
||||||
Unregister();
|
AssExportFilterChain::Unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,6 @@
|
||||||
/// @ingroup export
|
/// @ingroup export
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Headers
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
|
@ -44,33 +41,12 @@
|
||||||
#include "ass_override.h"
|
#include "ass_override.h"
|
||||||
#include "export_clean_info.h"
|
#include "export_clean_info.h"
|
||||||
|
|
||||||
|
AssTransformCleanInfoFilter::AssTransformCleanInfoFilter()
|
||||||
/// @brief Constructor
|
: AssExportFilter(_("Clean Script Info"), _("Removes all but the absolutely required fields from the Script Info section. You might want to run this on files that you plan to distribute in original form."))
|
||||||
///
|
{
|
||||||
AssTransformCleanInfoFilter::AssTransformCleanInfoFilter() {
|
|
||||||
initialized = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *) {
|
||||||
|
|
||||||
/// @brief Init
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
void AssTransformCleanInfoFilter::Init() {
|
|
||||||
if (initialized) return;
|
|
||||||
initialized = true;
|
|
||||||
autoExporter = false;
|
|
||||||
Register(_("Clean Script Info"),0);
|
|
||||||
description = _("Removes all but the absolutely required fields from the Script Info section. You might want to run this on files that you plan to distribute in original form.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Process
|
|
||||||
/// @param subs
|
|
||||||
/// @param export_dialog
|
|
||||||
///
|
|
||||||
void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
|
||||||
using std::list;
|
using std::list;
|
||||||
AssEntry *curEntry;
|
AssEntry *curEntry;
|
||||||
entryIter cur, next = subs->Line.begin();
|
entryIter cur, next = subs->Line.begin();
|
||||||
|
@ -78,53 +54,28 @@ void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *export_di
|
||||||
cur = next++;
|
cur = next++;
|
||||||
|
|
||||||
curEntry = *cur;
|
curEntry = *cur;
|
||||||
if (curEntry->group != _T("[Script Info]")) {
|
if (curEntry->group != "[Script Info]") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (curEntry->GetEntryData().IsEmpty()) {
|
if (curEntry->GetEntryData().empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (curEntry->GetEntryData() == _T("[Script Info]")) {
|
if (curEntry->GetEntryData() == "[Script Info]") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (curEntry->GetEntryData().Left(1) == _T(";")) {
|
if (curEntry->GetEntryData().Left(1) == ";") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString field = curEntry->GetEntryData().Left(curEntry->GetEntryData().Find(_T(':'))).Lower();
|
wxString field = curEntry->GetEntryData().Left(curEntry->GetEntryData().Find(_T(':'))).Lower();
|
||||||
if (field != _T("scripttype") &&
|
if (field != "scripttype" &&
|
||||||
field != _T("collisions") &&
|
field != "collisions" &&
|
||||||
field != _T("playresx") &&
|
field != "playresx" &&
|
||||||
field != _T("playresy") &&
|
field != "playresy" &&
|
||||||
field != _T("wrapstyle") &&
|
field != "wrapstyle" &&
|
||||||
field != _T("scaledborderandshadow")) {
|
field != "scaledborderandshadow") {
|
||||||
delete curEntry;
|
delete curEntry;
|
||||||
subs->Line.erase(cur);
|
subs->Line.erase(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Get dialog
|
|
||||||
/// @param parent
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
wxWindow *AssTransformCleanInfoFilter::GetConfigDialogWindow(wxWindow *parent) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Load settings
|
|
||||||
/// @param IsDefault
|
|
||||||
///
|
|
||||||
void AssTransformCleanInfoFilter::LoadSettings(bool IsDefault) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
AssTransformCleanInfoFilter AssTransformCleanInfoFilter::instance;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,32 +34,16 @@
|
||||||
/// @ingroup export
|
/// @ingroup export
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Headers
|
|
||||||
#include "ass_export_filter.h"
|
#include "ass_export_filter.h"
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class AssTransformCleanInfoFilter
|
/// @class AssTransformCleanInfoFilter
|
||||||
/// @brief DOCME
|
/// @brief Removes all but the absolutely required fields from the Script Info section
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class AssTransformCleanInfoFilter : public AssExportFilter {
|
class AssTransformCleanInfoFilter : public AssExportFilter {
|
||||||
private:
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static AssTransformCleanInfoFilter instance;
|
|
||||||
|
|
||||||
AssTransformCleanInfoFilter();
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||||
wxWindow *GetConfigDialogWindow(wxWindow *parent);
|
AssTransformCleanInfoFilter();
|
||||||
void LoadSettings(bool IsDefault);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,37 +46,22 @@
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "ass_style.h"
|
#include "ass_style.h"
|
||||||
|
|
||||||
/// @brief Constructor
|
AssFixStylesFilter::AssFixStylesFilter()
|
||||||
AssFixStylesFilter::AssFixStylesFilter() {
|
: AssExportFilter(_("Fix Styles"), _("Fixes styles by replacing any style that isn't available on file with Default."), -5000)
|
||||||
initialized = false;
|
{
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Init
|
|
||||||
void AssFixStylesFilter::Init() {
|
|
||||||
if (initialized) return;
|
|
||||||
initialized = true;
|
|
||||||
autoExporter = true;
|
autoExporter = true;
|
||||||
Register(_("Fix Styles"),-5000);
|
|
||||||
description = _("Fixes styles by replacing any style that isn't available on file with Default.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Process
|
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *) {
|
||||||
/// @param subs
|
|
||||||
/// @param export_dialog
|
|
||||||
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
|
||||||
wxArrayString styles = subs->GetStyles();
|
wxArrayString styles = subs->GetStyles();
|
||||||
std::for_each(styles.begin(), styles.end(), std::mem_fun_ref(&wxString::MakeLower));
|
for_each(styles.begin(), styles.end(), std::mem_fun_ref(&wxString::MakeLower));
|
||||||
styles.Sort();
|
styles.Sort();
|
||||||
|
|
||||||
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
|
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(*cur);
|
if (AssDialogue *diag = dynamic_cast<AssDialogue*>(*cur)) {
|
||||||
if (diag) {
|
|
||||||
if (!std::binary_search(styles.begin(), styles.end(), diag->Style.Lower())) {
|
if (!std::binary_search(styles.begin(), styles.end(), diag->Style.Lower())) {
|
||||||
diag->Style = L"Default";
|
diag->Style = "Default";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
AssFixStylesFilter AssFixStylesFilter::instance;
|
|
||||||
|
|
|
@ -34,29 +34,18 @@
|
||||||
/// @ingroup export
|
/// @ingroup export
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Headers
|
|
||||||
#include "ass_export_filter.h"
|
#include "ass_export_filter.h"
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class AssFixStylesFilter
|
/// @class AssFixStylesFilter
|
||||||
/// @brief DOCME
|
/// @brief Fixes styles by replacing any style that isn't available on file with Default
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class AssFixStylesFilter : public AssExportFilter {
|
class AssFixStylesFilter : public AssExportFilter {
|
||||||
private:
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
static AssFixStylesFilter instance;
|
|
||||||
AssFixStylesFilter();
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||||
|
AssFixStylesFilter();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,36 +55,16 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
/// @class LineData
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
/// DOCME
|
|
||||||
struct LineData {
|
|
||||||
AssDialogue *line;
|
|
||||||
int newStart;
|
|
||||||
int newEnd;
|
|
||||||
int newK;
|
|
||||||
int oldK;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// IDs
|
/// IDs
|
||||||
enum {
|
enum {
|
||||||
Get_Input_From_Video = 2000
|
Get_Input_From_Video = 2000
|
||||||
};
|
};
|
||||||
|
|
||||||
AssTransformFramerateFilter::AssTransformFramerateFilter() {
|
AssTransformFramerateFilter::AssTransformFramerateFilter()
|
||||||
initialized = false;
|
: AssExportFilter(_("Transform Framerate"), _("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup."), 1000)
|
||||||
}
|
, Input(0)
|
||||||
|
, Output(0)
|
||||||
void AssTransformFramerateFilter::Init() {
|
{
|
||||||
if (initialized) return;
|
|
||||||
initialized = true;
|
|
||||||
autoExporter = true;
|
|
||||||
Register(_("Transform Framerate"),1000);
|
|
||||||
description = _("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup.");
|
|
||||||
Input = NULL;
|
|
||||||
Output = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
|
||||||
|
@ -100,9 +80,10 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
|
||||||
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
|
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
wxString initialInput;
|
wxString initialInput;
|
||||||
wxButton *FromVideo = new wxButton(base,Get_Input_From_Video,_("From Video"));
|
wxButton *FromVideo = new wxButton(base,Get_Input_From_Video,_("From Video"));
|
||||||
if (Input->IsLoaded()) initialInput = wxString::Format(_T("%2.3f"),Input->FPS());
|
if (Input->IsLoaded())
|
||||||
|
initialInput = wxString::Format("%2.3f",Input->FPS());
|
||||||
else {
|
else {
|
||||||
initialInput = _T("23.976");
|
initialInput = "23.976";
|
||||||
FromVideo->Enable(false);
|
FromVideo->Enable(false);
|
||||||
}
|
}
|
||||||
InputFramerate = new wxTextCtrl(base,-1,initialInput,wxDefaultPosition,wxSize(60,20));
|
InputFramerate = new wxTextCtrl(base,-1,initialInput,wxDefaultPosition,wxSize(60,20));
|
||||||
|
@ -179,18 +160,18 @@ int FORCEINLINE trunc_cs(int time) {
|
||||||
return (time / 10) * 10;
|
return (time / 10) * 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssTransformFramerateFilter::TransformTimeTags (wxString name,int n,AssOverrideParameter *curParam,void *curData) {
|
void AssTransformFramerateFilter::TransformTimeTags(wxString name,int n,AssOverrideParameter *curParam,void *curData) {
|
||||||
VariableDataType type = curParam->GetType();
|
VariableDataType type = curParam->GetType();
|
||||||
if (type != VARDATA_INT && type != VARDATA_FLOAT) return;
|
if (type != VARDATA_INT && type != VARDATA_FLOAT) return;
|
||||||
|
|
||||||
LineData *lineData = static_cast<LineData*>(curData);
|
AssTransformFramerateFilter *instance = static_cast<AssTransformFramerateFilter*>(curData);
|
||||||
AssDialogue *curDiag = lineData->line;
|
AssDialogue *curDiag = instance->line;
|
||||||
|
|
||||||
int parVal = curParam->Get<int>();
|
int parVal = curParam->Get<int>();
|
||||||
|
|
||||||
switch (curParam->classification) {
|
switch (curParam->classification) {
|
||||||
case PARCLASS_RELATIVE_TIME_START: {
|
case PARCLASS_RELATIVE_TIME_START: {
|
||||||
int value = instance.ConvertTime(trunc_cs(curDiag->Start.GetMS()) + parVal) - lineData->newStart;
|
int value = instance->ConvertTime(trunc_cs(curDiag->Start.GetMS()) + parVal) - instance->newStart;
|
||||||
|
|
||||||
// An end time of 0 is actually the end time of the line, so ensure
|
// An end time of 0 is actually the end time of the line, so ensure
|
||||||
// nonzero is never converted to 0
|
// nonzero is never converted to 0
|
||||||
|
@ -202,13 +183,13 @@ void AssTransformFramerateFilter::TransformTimeTags (wxString name,int n,AssOver
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PARCLASS_RELATIVE_TIME_END:
|
case PARCLASS_RELATIVE_TIME_END:
|
||||||
curParam->Set(lineData->newEnd - instance.ConvertTime(trunc_cs(curDiag->End.GetMS()) - parVal));
|
curParam->Set(instance->newEnd - instance->ConvertTime(trunc_cs(curDiag->End.GetMS()) - parVal));
|
||||||
break;
|
break;
|
||||||
case PARCLASS_KARAOKE: {
|
case PARCLASS_KARAOKE: {
|
||||||
int start = curDiag->Start.GetMS() / 10 + lineData->oldK + parVal;
|
int start = curDiag->Start.GetMS() / 10 + instance->oldK + parVal;
|
||||||
int value = (instance.ConvertTime(start * 10) - lineData->newStart) / 10 - lineData->newK;
|
int value = (instance->ConvertTime(start * 10) - instance->newStart) / 10 - instance->newK;
|
||||||
lineData->oldK += parVal;
|
instance->oldK += parVal;
|
||||||
lineData->newK += value;
|
instance->newK += value;
|
||||||
curParam->Set(value);
|
curParam->Set(value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -223,18 +204,17 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
|
||||||
AssDialogue *curDialogue = dynamic_cast<AssDialogue*>(*cur);
|
AssDialogue *curDialogue = dynamic_cast<AssDialogue*>(*cur);
|
||||||
|
|
||||||
if (curDialogue) {
|
if (curDialogue) {
|
||||||
LineData data;
|
line = curDialogue;
|
||||||
data.line = curDialogue;
|
newK = 0;
|
||||||
data.newK = 0;
|
oldK = 0;
|
||||||
data.oldK = 0;
|
newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
|
||||||
data.newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
|
newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
|
||||||
data.newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
|
|
||||||
|
|
||||||
// Process stuff
|
// Process stuff
|
||||||
curDialogue->ParseASSTags();
|
curDialogue->ParseASSTags();
|
||||||
curDialogue->ProcessParameters(TransformTimeTags,&data);
|
curDialogue->ProcessParameters(TransformTimeTags, this);
|
||||||
curDialogue->Start.SetMS(data.newStart);
|
curDialogue->Start.SetMS(newStart);
|
||||||
curDialogue->End.SetMS(data.newEnd);
|
curDialogue->End.SetMS(newEnd);
|
||||||
curDialogue->UpdateText();
|
curDialogue->UpdateText();
|
||||||
curDialogue->ClearBlocks();
|
curDialogue->ClearBlocks();
|
||||||
}
|
}
|
||||||
|
@ -254,5 +234,3 @@ int AssTransformFramerateFilter::ConvertTime(int time) {
|
||||||
|
|
||||||
return newStart + newDur * dist;
|
return newStart + newDur * dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssTransformFramerateFilter AssTransformFramerateFilter::instance;
|
|
||||||
|
|
|
@ -45,38 +45,36 @@ class wxTextCtrl;
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class AssTransformFramerateFilter
|
/// @class AssTransformFramerateFilter
|
||||||
/// @brief DOCME
|
/// @brief Transform subtitle times, including those in override tags, from an input framerate to an output framerate
|
||||||
class AssTransformFramerateFilter : public AssExportFilter {
|
class AssTransformFramerateFilter : public AssExportFilter {
|
||||||
/// The singleton instance of this filter
|
AssDialogue *line;
|
||||||
static AssTransformFramerateFilter instance;
|
int newStart;
|
||||||
|
int newEnd;
|
||||||
|
int newK;
|
||||||
|
int oldK;
|
||||||
|
|
||||||
// Yes, these are backwards
|
// Yes, these are backwards
|
||||||
const agi::vfr::Framerate *Input; /// Destination frame rate
|
const agi::vfr::Framerate *Input; ///< Destination frame rate
|
||||||
const agi::vfr::Framerate *Output; /// Source frame rate
|
const agi::vfr::Framerate *Output; ///< Source frame rate
|
||||||
|
|
||||||
agi::vfr::Framerate t1,t2;
|
agi::vfr::Framerate t1,t2;
|
||||||
|
|
||||||
wxTextCtrl *InputFramerate; /// Input frame rate text box
|
wxTextCtrl *InputFramerate; ///< Input frame rate text box
|
||||||
wxTextCtrl *OutputFramerate; /// Output frame rate text box
|
wxTextCtrl *OutputFramerate; ///< Output frame rate text box
|
||||||
|
|
||||||
wxRadioButton *RadioOutputCFR; /// CFR radio control
|
wxRadioButton *RadioOutputCFR; ///< CFR radio control
|
||||||
wxRadioButton *RadioOutputVFR; /// VFR radio control
|
wxRadioButton *RadioOutputVFR; ///< VFR radio control
|
||||||
|
|
||||||
wxCheckBox *Reverse; /// Switch input and output
|
wxCheckBox *Reverse; ///< Switch input and output
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
AssTransformFramerateFilter();
|
|
||||||
|
|
||||||
/// @brief Apply the transformation to a file
|
/// @brief Apply the transformation to a file
|
||||||
/// @param subs File to process
|
/// @param subs File to process
|
||||||
void TransformFrameRate(AssFile *subs);
|
void TransformFrameRate(AssFile *subs);
|
||||||
/// @brief Transform a single tag
|
/// @brief Transform a single tag
|
||||||
/// @param name Name of the tag
|
/// @param name Name of the tag
|
||||||
/// @param curParam Current parameter being processed
|
/// @param curParam Current parameter being processed
|
||||||
/// @param userdata LineData passed
|
/// @param userdata Filter instance
|
||||||
static void TransformTimeTags(wxString name,int,AssOverrideParameter *curParam,void *userdata);
|
static void TransformTimeTags(wxString name,int,AssOverrideParameter *curParam,void *userdata);
|
||||||
/// Initialize the singleton instance
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
/// @brief Convert a time from the input frame rate to the output frame rate
|
/// @brief Convert a time from the input frame rate to the output frame rate
|
||||||
/// @param time Time in ms to convert
|
/// @param time Time in ms to convert
|
||||||
|
@ -88,6 +86,8 @@ class AssTransformFramerateFilter : public AssExportFilter {
|
||||||
/// is in and the beginning of the next frame
|
/// is in and the beginning of the next frame
|
||||||
int ConvertTime(int time);
|
int ConvertTime(int time);
|
||||||
public:
|
public:
|
||||||
|
/// Constructor
|
||||||
|
AssTransformFramerateFilter();
|
||||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||||
wxWindow *GetConfigDialogWindow(wxWindow *parent);
|
wxWindow *GetConfigDialogWindow(wxWindow *parent);
|
||||||
void LoadSettings(bool IsDefault);
|
void LoadSettings(bool IsDefault);
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
#endif
|
#endif
|
||||||
#include "charset_conv.h"
|
#include "charset_conv.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
#include "export_clean_info.h"
|
||||||
|
#include "export_fixstyle.h"
|
||||||
#include "export_framerate.h"
|
#include "export_framerate.h"
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
@ -285,8 +287,10 @@ bool AegisubApp::OnInit() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load export filters
|
// Load export filters
|
||||||
StartupLog(_T("Prepare export filters"));
|
StartupLog(L"Register export filters");
|
||||||
AssExportFilterChain::PrepareFilters();
|
AssExportFilterChain::Register(new AssFixStylesFilter);
|
||||||
|
AssExportFilterChain::Register(new AssTransformCleanInfoFilter);
|
||||||
|
AssExportFilterChain::Register(new AssTransformFramerateFilter);
|
||||||
|
|
||||||
// Get parameter subs
|
// Get parameter subs
|
||||||
StartupLog(_T("Parse command line"));
|
StartupLog(_T("Parse command line"));
|
||||||
|
|
Loading…
Reference in New Issue