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:
Thomas Goyne 2011-01-21 06:09:04 +00:00
parent 83a461ca63
commit af92002d8c
11 changed files with 131 additions and 378 deletions

View File

@ -39,178 +39,53 @@
#include "ass_export_filter.h"
#include "ass_file.h"
/// @brief Constructor
///
AssExportFilter::AssExportFilter() {
hidden = false;
autoExporter = false;
initialized = false;
FilterList *fil = AssExportFilterChain::GetUnpreparedFilterList();
fil->push_back(this);
AssExportFilter::AssExportFilter(wxString const& name, wxString const& description, int priority)
: name(name)
, priority(priority)
, autoExporter(false)
, hidden(false)
, description(description)
{
}
/// @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(""));
void AssExportFilterChain::Register(AssExportFilter *filter) {
// 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;
wxString tmpnam;
if (filter_copy == 0) {
tmpnam = name;
} else {
wxString tmpnam = filter->name;
if (false) {
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
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
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
filter_copy++;
goto try_new_name;
}
}
// Set name
RegisterName = tmpnam;
Priority = priority;
filter->name = tmpnam;
// Look for place to insert
bool inserted = false;
for (FilterList::iterator cur=begin;cur!=end;cur++) {
if ((*cur)->Priority < Priority) {
AssExportFilterChain::GetFilterList()->insert(cur,this);
inserted = true;
break;
}
}
if (!inserted) AssExportFilterChain::GetFilterList()->push_back(this);
while (begin != end && (*begin)->priority >= filter->priority) ++begin;
GetFilterList()->insert(begin, filter);
}
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);
/// @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);
GetFilterList()->remove(filter);
}
/// @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() {
if (!instance.get()) instance.reset(new AssExportFilterChain());
return &(instance->Filters);
}
/// @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();
static FilterList instance;
return &instance;
}

View File

@ -58,24 +58,19 @@ typedef std::list<AssExportFilter*> FilterList;
///
/// DOCME
class AssExportFilterChain {
friend class AssExportFilter;
friend class AssExporter;
private:
/// DOCME
/// The list of registered filters
FilterList Filters;
/// DOCME
FilterList Unprepared;
/// DOCME
static std::auto_ptr<AssExportFilterChain> instance;
/// Get the singleton instance
static FilterList *GetFilterList();
static FilterList *GetUnpreparedFilterList();
AssExportFilterChain() { }
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
@ -87,41 +82,33 @@ class AssExportFilter {
friend class AssExporter;
friend class AssExportFilterChain;
private:
/// This filter's name
wxString name;
/// DOCME
wxString RegisterName;
/// DOCME
int Priority;
/// Higher priority = run earlier
int priority;
protected:
/// DOCME
/// Should this filter be used when sending subtitles to the subtitle provider
bool autoExporter;
/// DOCME
/// Should this filter be hidden from the user
bool hidden;
/// DOCME
bool initialized;
/// DOCME
/// User-visible description of this filter
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:
AssExportFilter();
virtual ~AssExportFilter();
AssExportFilter(wxString const& name, wxString const& description, int priority = 0);
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.
virtual wxWindow *GetConfigDialogWindow(wxWindow *parent); // Draw setup controls - this function may optionally be overridden.
virtual void LoadSettings(bool IsDefault); // Config dialog is done - extract data now.
/// Process subtitles
virtual void ProcessSubs(AssFile *subs, wxWindow *export_dialog=0)=0;
/// Draw setup controls
virtual wxWindow *GetConfigDialogWindow(wxWindow *parent) { return 0; }
/// Config dialog is done - extract data now.
virtual void LoadSettings(bool IsDefault) { }
};

View File

@ -67,13 +67,13 @@ void AssExporter::DrawSettings(wxWindow *parent,wxSizer *AddTo) {
for (FilterList::iterator cur=begin;cur!=end;cur++) {
// Make sure to construct static box sizer first, so it won't overlap
// the controls on wxMac.
box = new wxStaticBoxSizer(wxVERTICAL,parent,(*cur)->RegisterName);
box = new wxStaticBoxSizer(wxVERTICAL,parent,(*cur)->name);
window = (*cur)->GetConfigDialogWindow(parent);
if (window) {
box->Add(window,0,wxEXPAND,0);
AddTo->Add(box,0,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,5);
AddTo->Show(box,false);
Sizers[(*cur)->RegisterName] = box;
Sizers[(*cur)->name] = box;
}
else {
delete box;
@ -90,13 +90,14 @@ void AssExporter::AddFilter(wxString name) {
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
for (FilterList::iterator cur=begin;cur!=end;cur++) {
if ((*cur)->RegisterName == name) {
if ((*cur)->name == name) {
filter = *cur;
break;
}
}
// 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
Filters.push_back(filter);
@ -122,7 +123,7 @@ wxArrayString AssExporter::GetAllFilterNames() {
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
for (FilterList::iterator cur=begin;cur!=end;cur++) {
if (!(*cur)->hidden) names.Add((*cur)->RegisterName);
if (!(*cur)->hidden) names.Add((*cur)->name);
}
return names;
}
@ -172,9 +173,9 @@ wxString AssExporter::GetDescription(wxString name) {
FilterList::iterator begin = AssExportFilterChain::GetFilterList()->begin();
FilterList::iterator end = AssExportFilterChain::GetFilterList()->end();
for (FilterList::iterator cur=begin;cur!=end;cur++) {
if ((*cur)->RegisterName == name) {
if ((*cur)->name == name) {
return (*cur)->GetDescription();
}
}
throw wxString::Format(_T("Filter not found: %s"), name.c_str());
throw wxString::Format("Filter not found: %s", name.c_str());
}

View File

@ -291,11 +291,10 @@ namespace Automation4 {
///
FeatureFilter::FeatureFilter(const wxString &_name, const wxString &_description, int _priority)
: Feature(SCRIPTFEATURE_FILTER, _name)
, AssExportFilter()
, AssExportFilter(_name, _description, _priority)
, config_dialog(0)
{
description = _description; // from AssExportFilter
Register(_name, _priority);
AssExportFilterChain::Register(this);
}
@ -303,7 +302,7 @@ namespace Automation4 {
///
FeatureFilter::~FeatureFilter()
{
Unregister();
AssExportFilterChain::Unregister(this);
}

View File

@ -34,9 +34,6 @@
/// @ingroup export
///
///////////
// Headers
#include "config.h"
#include "ass_dialogue.h"
@ -44,33 +41,12 @@
#include "ass_override.h"
#include "export_clean_info.h"
/// @brief Constructor
///
AssTransformCleanInfoFilter::AssTransformCleanInfoFilter() {
initialized = false;
AssTransformCleanInfoFilter::AssTransformCleanInfoFilter()
: 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."))
{
}
/// @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) {
void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *) {
using std::list;
AssEntry *curEntry;
entryIter cur, next = subs->Line.begin();
@ -78,53 +54,28 @@ void AssTransformCleanInfoFilter::ProcessSubs(AssFile *subs, wxWindow *export_di
cur = next++;
curEntry = *cur;
if (curEntry->group != _T("[Script Info]")) {
if (curEntry->group != "[Script Info]") {
continue;
}
if (curEntry->GetEntryData().IsEmpty()) {
if (curEntry->GetEntryData().empty()) {
continue;
}
if (curEntry->GetEntryData() == _T("[Script Info]")) {
if (curEntry->GetEntryData() == "[Script Info]") {
continue;
}
if (curEntry->GetEntryData().Left(1) == _T(";")) {
if (curEntry->GetEntryData().Left(1) == ";") {
continue;
}
wxString field = curEntry->GetEntryData().Left(curEntry->GetEntryData().Find(_T(':'))).Lower();
if (field != _T("scripttype") &&
field != _T("collisions") &&
field != _T("playresx") &&
field != _T("playresy") &&
field != _T("wrapstyle") &&
field != _T("scaledborderandshadow")) {
if (field != "scripttype" &&
field != "collisions" &&
field != "playresx" &&
field != "playresy" &&
field != "wrapstyle" &&
field != "scaledborderandshadow") {
delete curEntry;
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;

View File

@ -34,32 +34,16 @@
/// @ingroup export
///
///////////
// Headers
#include "ass_export_filter.h"
/// DOCME
/// @class AssTransformCleanInfoFilter
/// @brief DOCME
/// @brief Removes all but the absolutely required fields from the Script Info section
///
/// DOCME
class AssTransformCleanInfoFilter : public AssExportFilter {
private:
/// DOCME
static AssTransformCleanInfoFilter instance;
AssTransformCleanInfoFilter();
void Init();
public:
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
wxWindow *GetConfigDialogWindow(wxWindow *parent);
void LoadSettings(bool IsDefault);
AssTransformCleanInfoFilter();
};

View File

@ -46,37 +46,22 @@
#include "ass_dialogue.h"
#include "ass_style.h"
/// @brief Constructor
AssFixStylesFilter::AssFixStylesFilter() {
initialized = false;
}
/// @brief Init
void AssFixStylesFilter::Init() {
if (initialized) return;
initialized = true;
AssFixStylesFilter::AssFixStylesFilter()
: AssExportFilter(_("Fix Styles"), _("Fixes styles by replacing any style that isn't available on file with Default."), -5000)
{
autoExporter = true;
Register(_("Fix Styles"),-5000);
description = _("Fixes styles by replacing any style that isn't available on file with Default.");
}
/// @brief Process
/// @param subs
/// @param export_dialog
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *) {
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();
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
AssDialogue *diag = dynamic_cast<AssDialogue*>(*cur);
if (diag) {
if (AssDialogue *diag = dynamic_cast<AssDialogue*>(*cur)) {
if (!std::binary_search(styles.begin(), styles.end(), diag->Style.Lower())) {
diag->Style = L"Default";
diag->Style = "Default";
}
}
}
}
/// DOCME
AssFixStylesFilter AssFixStylesFilter::instance;

View File

@ -34,29 +34,18 @@
/// @ingroup export
///
///////////
// Headers
#include "ass_export_filter.h"
/// DOCME
/// @class AssFixStylesFilter
/// @brief DOCME
/// @brief Fixes styles by replacing any style that isn't available on file with Default
///
/// DOCME
class AssFixStylesFilter : public AssExportFilter {
private:
/// DOCME
static AssFixStylesFilter instance;
AssFixStylesFilter();
void Init();
public:
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
AssFixStylesFilter();
};

View File

@ -55,36 +55,16 @@
#include "utils.h"
#include "video_context.h"
/// DOCME
/// @class LineData
/// @brief DOCME
///
/// DOCME
struct LineData {
AssDialogue *line;
int newStart;
int newEnd;
int newK;
int oldK;
};
/// IDs
enum {
Get_Input_From_Video = 2000
};
AssTransformFramerateFilter::AssTransformFramerateFilter() {
initialized = false;
}
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;
AssTransformFramerateFilter::AssTransformFramerateFilter()
: 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::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
@ -100,9 +80,10 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
wxString initialInput;
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 {
initialInput = _T("23.976");
initialInput = "23.976";
FromVideo->Enable(false);
}
InputFramerate = new wxTextCtrl(base,-1,initialInput,wxDefaultPosition,wxSize(60,20));
@ -179,18 +160,18 @@ int FORCEINLINE trunc_cs(int time) {
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();
if (type != VARDATA_INT && type != VARDATA_FLOAT) return;
LineData *lineData = static_cast<LineData*>(curData);
AssDialogue *curDiag = lineData->line;
AssTransformFramerateFilter *instance = static_cast<AssTransformFramerateFilter*>(curData);
AssDialogue *curDiag = instance->line;
int parVal = curParam->Get<int>();
switch (curParam->classification) {
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
// nonzero is never converted to 0
@ -202,13 +183,13 @@ void AssTransformFramerateFilter::TransformTimeTags (wxString name,int n,AssOver
break;
}
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;
case PARCLASS_KARAOKE: {
int start = curDiag->Start.GetMS() / 10 + lineData->oldK + parVal;
int value = (instance.ConvertTime(start * 10) - lineData->newStart) / 10 - lineData->newK;
lineData->oldK += parVal;
lineData->newK += value;
int start = curDiag->Start.GetMS() / 10 + instance->oldK + parVal;
int value = (instance->ConvertTime(start * 10) - instance->newStart) / 10 - instance->newK;
instance->oldK += parVal;
instance->newK += value;
curParam->Set(value);
break;
}
@ -223,18 +204,17 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
AssDialogue *curDialogue = dynamic_cast<AssDialogue*>(*cur);
if (curDialogue) {
LineData data;
data.line = curDialogue;
data.newK = 0;
data.oldK = 0;
data.newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
data.newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
line = curDialogue;
newK = 0;
oldK = 0;
newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
// Process stuff
curDialogue->ParseASSTags();
curDialogue->ProcessParameters(TransformTimeTags,&data);
curDialogue->Start.SetMS(data.newStart);
curDialogue->End.SetMS(data.newEnd);
curDialogue->ProcessParameters(TransformTimeTags, this);
curDialogue->Start.SetMS(newStart);
curDialogue->End.SetMS(newEnd);
curDialogue->UpdateText();
curDialogue->ClearBlocks();
}
@ -254,5 +234,3 @@ int AssTransformFramerateFilter::ConvertTime(int time) {
return newStart + newDur * dist;
}
AssTransformFramerateFilter AssTransformFramerateFilter::instance;

View File

@ -45,38 +45,36 @@ class wxTextCtrl;
/// DOCME
/// @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 {
/// The singleton instance of this filter
static AssTransformFramerateFilter instance;
AssDialogue *line;
int newStart;
int newEnd;
int newK;
int oldK;
// Yes, these are backwards
const agi::vfr::Framerate *Input; /// Destination frame rate
const agi::vfr::Framerate *Output; /// Source frame rate
const agi::vfr::Framerate *Input; ///< Destination frame rate
const agi::vfr::Framerate *Output; ///< Source frame rate
agi::vfr::Framerate t1,t2;
wxTextCtrl *InputFramerate; /// Input frame rate text box
wxTextCtrl *OutputFramerate; /// Output frame rate text box
wxTextCtrl *InputFramerate; ///< Input frame rate text box
wxTextCtrl *OutputFramerate; ///< Output frame rate text box
wxRadioButton *RadioOutputCFR; /// CFR radio control
wxRadioButton *RadioOutputVFR; /// VFR radio control
wxRadioButton *RadioOutputCFR; ///< CFR 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
/// @param subs File to process
void TransformFrameRate(AssFile *subs);
/// @brief Transform a single tag
/// @param name Name of the tag
/// @param curParam Current parameter being processed
/// @param userdata LineData passed
/// @param userdata Filter instance
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
/// @param time Time in ms to convert
@ -88,6 +86,8 @@ class AssTransformFramerateFilter : public AssExportFilter {
/// is in and the beginning of the next frame
int ConvertTime(int time);
public:
/// Constructor
AssTransformFramerateFilter();
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
wxWindow *GetConfigDialogWindow(wxWindow *parent);
void LoadSettings(bool IsDefault);

View File

@ -67,6 +67,8 @@
#endif
#include "charset_conv.h"
#include "compat.h"
#include "export_clean_info.h"
#include "export_fixstyle.h"
#include "export_framerate.h"
#include "frame_main.h"
#include "main.h"
@ -285,8 +287,10 @@ bool AegisubApp::OnInit() {
#endif
// Load export filters
StartupLog(_T("Prepare export filters"));
AssExportFilterChain::PrepareFilters();
StartupLog(L"Register export filters");
AssExportFilterChain::Register(new AssFixStylesFilter);
AssExportFilterChain::Register(new AssTransformCleanInfoFilter);
AssExportFilterChain::Register(new AssTransformFramerateFilter);
// Get parameter subs
StartupLog(_T("Parse command line"));