Change AssEntry::group to an enum

This commit is contained in:
Thomas Goyne 2012-11-24 16:08:29 -08:00
parent 49ed0551ad
commit 4e8e5b597c
15 changed files with 114 additions and 91 deletions

View File

@ -47,10 +47,11 @@
#include <libaegisub/io.h>
#include <libaegisub/scoped_ptr.h>
AssAttachment::AssAttachment(wxString const& name, wxString const& group)
: AssEntry(wxString(), group)
AssAttachment::AssAttachment(wxString const& name, AssEntryGroup group)
: AssEntry(wxString())
, data(new std::vector<char>)
, filename(name)
, group(group)
{
wxFileName fname(filename);
wxString ext = fname.GetExt().Lower();
@ -72,10 +73,7 @@ const wxString AssAttachment::GetEntryData() const {
unsigned char dst[4];
// Write header
wxString entryData;
if (group == "[Fonts]") entryData = "fontname: ";
else entryData = "filename: ";
entryData += filename + "\r\n";
wxString entryData = (group == ENTRY_FONT ? "fontname: " : "filename: ") + filename + "\r\n";
// Read three bytes
while (pos < size) {

View File

@ -51,6 +51,8 @@ class AssAttachment : public AssEntry {
/// Name of the attached file, with SSA font mangling if it is a ttf
wxString filename;
AssEntryGroup group;
public:
/// Get the size of the attached file in bytes
size_t GetSize() const { return data->size(); }
@ -74,8 +76,8 @@ public:
wxString GetFileName(bool raw=false) const;
const wxString GetEntryData() const;
AssEntryType GetType() const { return ENTRY_ATTACHMENT; }
AssEntryGroup Group() const { return group; }
AssEntry *Clone() const;
AssAttachment(wxString const& name, wxString const& group);
AssAttachment(wxString const& name, AssEntryGroup group);
};

View File

@ -49,7 +49,7 @@
#include "utils.h"
AssDialogue::AssDialogue()
: AssEntry(wxString(), "[Events]")
: AssEntry(wxString())
, Comment(false)
, Layer(0)
, Start(0)
@ -60,7 +60,7 @@ AssDialogue::AssDialogue()
}
AssDialogue::AssDialogue(AssDialogue const& that)
: AssEntry(wxString(), that.group)
: AssEntry(wxString())
, Comment(that.Comment)
, Layer(that.Layer)
, Start(that.Start)
@ -74,7 +74,7 @@ AssDialogue::AssDialogue(AssDialogue const& that)
}
AssDialogue::AssDialogue(wxString const& data)
: AssEntry(wxString(), "[Events]")
: AssEntry(wxString())
, Comment(false)
, Layer(0)
, Start(0)

View File

@ -143,7 +143,7 @@ public:
/// Raw text data
wxString Text;
AssEntryType GetType() const { return ENTRY_DIALOGUE; }
AssEntryGroup Group() const { return ENTRY_DIALOGUE; }
/// @brief Parse raw ASS data into everything else
/// @param data ASS line

View File

@ -42,5 +42,27 @@ wxString AssEntry::GetSSAText() const {
}
AssEntry *AssEntry::Clone() const {
return new AssEntry(data, group);
return new AssEntry(data);
}
wxString const& AssEntry::GroupHeader(bool ssa) const {
static wxString ass_headers[] = {
"[Script Info]",
"[Events]",
"[V4+ Styles]"
"[Fonts]",
"[Graphics]",
""
};
static wxString ssa_headers[] = {
"[Script Info]",
"[Events]",
"[V4 Styles]"
"[Fonts]",
"[Graphics]",
""
};
return (ssa ? ssa_headers : ass_headers)[Group()];
}

View File

@ -40,11 +40,13 @@
#include <boost/intrusive/list_hook.hpp>
enum AssEntryType {
ENTRY_BASE,
enum AssEntryGroup {
ENTRY_INFO = 0,
ENTRY_DIALOGUE,
ENTRY_STYLE,
ENTRY_ATTACHMENT
ENTRY_FONT,
ENTRY_GRAPHIC,
ENTRY_GROUP_MAX
};
class AssEntry : public boost::intrusive::make_list_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink> >::type {
@ -52,17 +54,17 @@ class AssEntry : public boost::intrusive::make_list_base_hook<boost::intrusive::
wxString data;
public:
/// Group it belongs to, e.g. "[Events]"
wxString group;
AssEntry(wxString const& data, wxString const& group) : data(data), group(group) { }
AssEntry(wxString const& data) : data(data) { }
virtual ~AssEntry() { }
/// Create a copy of this entry
virtual AssEntry *Clone() const;
/// Get this entry's fully-derived type
virtual AssEntryType GetType() const { return ENTRY_BASE; }
/// Section of the file this entry belongs to
virtual AssEntryGroup Group() const { return ENTRY_INFO; }
/// ASS or SSA Section header for this entry's group
wxString const& GroupHeader(bool ssa=false) const;
/// @brief Get this line's raw entry data in ASS format
virtual const wxString GetEntryData() const { return data; }

View File

@ -90,7 +90,7 @@ void AssFile::Load(const wxString &_filename, wxString const& charset) {
// Check if the file has at least one style and at least one dialogue line
for (auto const& line : temp.Line) {
AssEntryType type = line.GetType();
AssEntryGroup type = line.Group();
if (type == ENTRY_STYLE) found_style = true;
if (type == ENTRY_DIALOGUE) found_dialogue = true;
if (found_style && found_dialogue) break;
@ -187,11 +187,11 @@ void AssFile::SaveMemory(std::vector<char> &dst) {
dst.reserve(0x4000);
// Write file
wxString group;
AssEntryGroup group = ENTRY_GROUP_MAX;
for (auto const& line : Line) {
if (group != line.group) {
group = line.group;
write_line(group, dst);
if (group != line.Group()) {
group = line.Group();
write_line(line.GroupHeader(), dst);
}
write_line(line.GetEntryData(), dst);
}
@ -220,16 +220,16 @@ void AssFile::LoadDefault(bool defline) {
Clear();
// Write headers
Line.push_back(*new AssEntry("Title: Default Aegisub file", "[Script Info]"));
Line.push_back(*new AssEntry("ScriptType: v4.00+", "[Script Info]"));
Line.push_back(*new AssEntry("WrapStyle: 0", "[Script Info]"));
Line.push_back(*new AssEntry("ScaledBorderAndShadow: yes", "[Script Info]"));
Line.push_back(*new AssEntry("Collisions: Normal", "[Script Info]"));
Line.push_back(*new AssEntry("Title: Default Aegisub file"));
Line.push_back(*new AssEntry("ScriptType: v4.00+"));
Line.push_back(*new AssEntry("WrapStyle: 0"));
Line.push_back(*new AssEntry("ScaledBorderAndShadow: yes"));
Line.push_back(*new AssEntry("Collisions: Normal"));
if (!OPT_GET("Subtitle/Default Resolution/Auto")->GetBool()) {
Line.push_back(*new AssEntry(wxString::Format("PlayResX: %" PRId64, OPT_GET("Subtitle/Default Resolution/Width")->GetInt()), "[Script Info]"));
Line.push_back(*new AssEntry(wxString::Format("PlayResY: %" PRId64, OPT_GET("Subtitle/Default Resolution/Height")->GetInt()), "[Script Info]"));
Line.push_back(*new AssEntry(wxString::Format("PlayResX: %" PRId64, OPT_GET("Subtitle/Default Resolution/Width")->GetInt())));
Line.push_back(*new AssEntry(wxString::Format("PlayResY: %" PRId64, OPT_GET("Subtitle/Default Resolution/Height")->GetInt())));
}
Line.push_back(*new AssEntry("YCbCr Matrix: None", "[Script Info]"));
Line.push_back(*new AssEntry("YCbCr Matrix: None"));
Line.push_back(*new AssStyle);
@ -275,7 +275,7 @@ void AssFile::InsertLine( AssEntry *entry) {
entryIter it = Line.end();
do {
--it;
if (it->group == entry->group) {
if (it->Group() == entry->Group()) {
Line.insert(++it, *entry);
return;
}
@ -285,11 +285,11 @@ void AssFile::InsertLine( AssEntry *entry) {
}
void AssFile::InsertAttachment(wxString filename) {
wxString group("[Graphics]");
AssEntryGroup group = ENTRY_GRAPHIC;
wxString ext = filename.Right(4).Lower();
if (ext == ".ttf" || ext == ".ttc" || ext == ".pfb")
group = "[Fonts]";
group = ENTRY_FONT;
std::unique_ptr<AssAttachment> newAttach(new AssAttachment(wxFileName(filename).GetFullName(), group));
newAttach->Import(filename);
@ -303,7 +303,7 @@ wxString AssFile::GetScriptInfo(wxString key) const {
bool GotIn = false;
for (auto const& line : Line) {
if (line.group == "[Script Info]") {
if (line.Group() == ENTRY_INFO) {
GotIn = true;
wxString curText = line.GetEntryData();
if (curText.Lower().StartsWith(key))
@ -328,7 +328,7 @@ void AssFile::SetScriptInfo(wxString const& key, wxString const& value) {
bool found_script_info = false;
for (auto& line : Line) {
if (line.group == "[Script Info]") {
if (line.Group() == ENTRY_INFO) {
found_script_info = true;
wxString cur_text = line.GetEntryData().Left(key_size).Lower();
@ -343,7 +343,7 @@ void AssFile::SetScriptInfo(wxString const& key, wxString const& value) {
}
else if (found_script_info) {
if (value.size())
Line.insert(script_info_end, *new AssEntry(key + ": " + value, "[Script Info]"));
Line.insert(script_info_end, *new AssEntry(key + ": " + value));
return;
}
}
@ -351,10 +351,10 @@ void AssFile::SetScriptInfo(wxString const& key, wxString const& value) {
// Found a script info section, but not this key or anything after it,
// so add it at the end of the file
if (found_script_info)
Line.push_back(*new AssEntry(key + ": " + value, "[Script Info]"));
Line.push_back(*new AssEntry(key + ": " + value));
// Script info section not found, so add it at the beginning of the file
else {
Line.push_front(*new AssEntry(key + ": " + value, "[Script Info]"));
Line.push_front(*new AssEntry(key + ": " + value));
}
}

View File

@ -23,6 +23,8 @@
#include "subtitle_format.h"
#ifndef AGI_PRE
#include <algorithm>
#include <wx/log.h>
#endif
@ -32,6 +34,7 @@ AssParser::AssParser(AssFile *target, int version)
, attach(nullptr)
, state(&AssParser::ParseScriptInfoLine)
{
std::fill(begin(insertion_positions), end(insertion_positions), nullptr);
}
AssParser::~AssParser() {
@ -87,7 +90,7 @@ void AssParser::ParseScriptInfoLine(wxString const& data) {
}
}
InsertLine(new AssEntry(data, "[Script Info]"));
InsertLine(new AssEntry(data));
}
void AssParser::ParseEventLine(wxString const& data) {
@ -102,12 +105,12 @@ void AssParser::ParseStyleLine(wxString const& data) {
void AssParser::ParseFontLine(wxString const& data) {
if (data.StartsWith("fontname: "))
attach.reset(new AssAttachment(data.Mid(10), "[Fonts]"));
attach.reset(new AssAttachment(data.Mid(10), ENTRY_FONT));
}
void AssParser::ParseGraphicsLine(wxString const& data) {
if (data.StartsWith("filename: "))
attach.reset(new AssAttachment(data.Mid(10), "[Graphics]"));
attach.reset(new AssAttachment(data.Mid(10), ENTRY_GRAPHIC));
}
void AssParser::AddLine(wxString const& data) {
@ -153,10 +156,10 @@ void AssParser::AddLine(wxString const& data) {
}
void AssParser::InsertLine(AssEntry *entry) {
auto it = insertion_positions.find(entry->group);
if (it == insertion_positions.end())
target->Line.push_back(*entry);
AssEntry *position = insertion_positions[entry->Group()];
if (position)
target->Line.insert(++target->Line.iterator_to(*position), *entry);
else
target->Line.insert(++target->Line.iterator_to(*it->second), *entry);
insertion_positions[entry->group] = entry;
target->Line.push_back(*entry);
insertion_positions[entry->Group()] = entry;
}

View File

@ -13,14 +13,16 @@
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifndef AGI_PRE
#include <array>
#include <map>
#include <memory>
#include <wx/string.h>
#endif
#include "ass_entry.h"
class AssAttachment;
class AssEntry;
class AssFile;
class AssParser {
@ -28,7 +30,7 @@ class AssParser {
int version;
std::unique_ptr<AssAttachment> attach;
void (AssParser::*state)(wxString const&);
std::map<wxString, AssEntry*> insertion_positions;
std::array<AssEntry*, ENTRY_GROUP_MAX> insertion_positions;
void InsertLine(AssEntry *entry);

View File

@ -47,7 +47,7 @@
#include "utils.h"
AssStyle::AssStyle()
: AssEntry(wxString(), wxS("[V4+ Styles]"))
: AssEntry(wxString())
, name("Default")
, font("Arial")
, fontsize(20.)
@ -92,7 +92,7 @@ static double get_next_double(wxStringTokenizer &tok) {
}
AssStyle::AssStyle(wxString rawData, int version)
: AssEntry(wxString(), wxS("[V4+ Styles]"))
: AssEntry(wxString())
{
wxStringTokenizer tkn(rawData.Trim(false).Mid(6), ",", wxTOKEN_RET_EMPTY_ALL);
@ -174,9 +174,8 @@ AssStyle::AssStyle(wxString rawData, int version)
void AssStyle::UpdateData() {
wxString final;
//name.Replace(",",";");
//font.Replace(",",";");
name.Replace(",",";");
font.Replace(",",";");
final = wxString::Format("Style: %s,%s,%g,%s,%s,%s,%s,%d,%d,%d,%d,%g,%g,%g,%g,%d,%g,%g,%i,%i,%i,%i,%i",
name, font, fontsize,

View File

@ -79,7 +79,7 @@ public:
AssStyle(wxString data, int version=1);
wxString GetSSAText() const;
AssEntryType GetType() const { return ENTRY_STYLE; }
AssEntryGroup GetType() const { return ENTRY_STYLE; }
AssEntry *Clone() const;
/// Convert an ASS alignment to the equivalent SSA alignment

View File

@ -178,12 +178,13 @@ namespace {
int modification_mask(AssEntry *e)
{
switch (e->GetType())
switch (e->Group())
{
case ENTRY_DIALOGUE: return AssFile::COMMIT_DIAG_ADDREM;
case ENTRY_STYLE: return AssFile::COMMIT_STYLES;
case ENTRY_ATTACHMENT: return AssFile::COMMIT_ATTACHMENT;
default: return AssFile::COMMIT_SCRIPTINFO;
case ENTRY_STYLE: return AssFile::COMMIT_STYLES;
case ENTRY_FONT: return AssFile::COMMIT_ATTACHMENT;
case ENTRY_GRAPHIC: return AssFile::COMMIT_ATTACHMENT;
default: return AssFile::COMMIT_SCRIPTINFO;
}
}
}
@ -207,13 +208,10 @@ namespace Automation4 {
wxString raw(e->GetEntryData());
set_field(L, "section", e->group);
set_field(L, "section", e->GroupHeader());
set_field(L, "raw", raw);
if (StringEmptyOrWhitespace(raw)) {
set_field(L, "class", "clear");
}
else if (e->group.Lower() == "[script info]") {
if (e->Group() == ENTRY_INFO) {
set_field(L, "key", raw.BeforeFirst(':'));
set_field(L, "value", raw.AfterFirst(':'));
set_field(L, "class", "info");
@ -280,6 +278,7 @@ namespace Automation4 {
set_field(L, "class", "style");
}
else {
// Attachments
set_field(L, "class", "unknown");
}
}
@ -306,7 +305,7 @@ namespace Automation4 {
wxString section = get_wxstring_field(L, "section", "common");
if (lclass == "info") {
result = new AssEntry(wxString::Format("%s: %s", get_wxstring_field(L, "key", "info"), get_wxstring_field(L, "value", "info")), "[Script Info]");
result = new AssEntry(wxString::Format("%s: %s", get_wxstring_field(L, "key", "info"), get_wxstring_field(L, "value", "info")));
}
else if (lclass == "style") {
AssStyle *sty = new AssStyle;
@ -530,10 +529,10 @@ namespace Automation4 {
do {
--it;
}
while (it != lines.begin() && (*it)->group != e->group);
while (it != lines.begin() && (*it)->Group() != e->Group());
}
if (it == lines.end() || (*it)->group != e->group) {
if (it == lines.end() || (*it)->Group() != e->Group()) {
// The new entry belongs to a group that doesn't exist yet, so
// create it at the end of the file
lines.push_back(e);

View File

@ -108,7 +108,7 @@ void DialogAttachments::UpdateList() {
int row = listView->GetItemCount();
listView->InsertItem(row,attach->GetFileName(true));
listView->SetItem(row,1,PrettySize(attach->GetSize()));
listView->SetItem(row,2,attach->group);
listView->SetItem(row,2,attach->GroupHeader());
listView->SetItemPtrData(row,wxPtrToUInt(attach));
}
}
@ -123,7 +123,7 @@ BEGIN_EVENT_TABLE(DialogAttachments,wxDialog)
EVT_LIST_ITEM_FOCUSED(ATTACHMENT_LIST,DialogAttachments::OnListClick)
END_EVENT_TABLE()
void DialogAttachments::AttachFile(wxFileDialog &diag, wxString const& group, wxString const& commit_msg) {
void DialogAttachments::AttachFile(wxFileDialog &diag, AssEntryGroup group, wxString const& commit_msg) {
if (diag.ShowModal() == wxID_CANCEL) return;
wxArrayString filenames;
@ -156,7 +156,7 @@ void DialogAttachments::OnAttachFont(wxCommandEvent &) {
lagi_wxString(OPT_GET("Path/Fonts Collector Destination")->GetString()), "", "Font Files (*.ttf)|*.ttf",
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
AttachFile(diag, "[Fonts]", _("attach font file"));
AttachFile(diag, ENTRY_FONT, _("attach font file"));
}
void DialogAttachments::OnAttachGraphics(wxCommandEvent &) {
@ -166,7 +166,7 @@ void DialogAttachments::OnAttachGraphics(wxCommandEvent &) {
"Graphic Files (*.bmp,*.gif,*.jpg,*.ico,*.wmf)|*.bmp;*.gif;*.jpg;*.ico;*.wmf",
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
AttachFile(diag, "[Graphics]", _("attach graphics file"));
AttachFile(diag, ENTRY_GRAPHIC, _("attach graphics file"));
}
void DialogAttachments::OnExtract(wxCommandEvent &) {

View File

@ -41,6 +41,8 @@ class wxListEvent;
#include <wx/dialog.h>
#endif
#include "ass_entry.h"
/// DOCME
/// @class DialogAttachments
/// @brief DOCME
@ -65,7 +67,7 @@ class DialogAttachments : public wxDialog {
void OnListClick(wxListEvent &event);
void UpdateList();
void AttachFile(wxFileDialog &diag, wxString const& group, wxString const& commit_msg);
void AttachFile(wxFileDialog &diag, AssEntryGroup group, wxString const& commit_msg);
public:
DialogAttachments(wxWindow *parent, AssFile *ass);

View File

@ -83,27 +83,21 @@ void AssSubtitleFormat::ReadFile(AssFile *target, wxString const& filename, wxSt
}
}
static inline wxString header(wxString const& group, bool ssa) {
if (ssa && group == "[V4+ Styles]")
return "[V4 Styles]";
return group;
}
#ifdef _WIN32
#define LINEBREAK "\r\n"
#else
#define LINEBREAK "\n"
#endif
static inline wxString format(wxString const& group, bool ssa) {
if (group == "[Events]") {
static inline wxString format(AssEntryGroup group, bool ssa) {
if (group == ENTRY_DIALOGUE) {
if (ssa)
return "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" LINEBREAK;
else
return "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" LINEBREAK;
}
if (group == "[v4+ styles]") {
if (group == ENTRY_STYLE) {
if (ssa)
return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding" LINEBREAK;
else
@ -120,18 +114,18 @@ void AssSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
file.WriteLineToFile("; http://www.aegisub.org/");
bool ssa = filename.Right(4).Lower() == ".ssa";
wxString group;
AssEntryGroup group = ENTRY_GROUP_MAX;
for (auto const& line : src->Line) {
if (line.group != group) {
if (line.Group() != group) {
// Add a blank line between each group
if (!group.empty())
if (group != ENTRY_GROUP_MAX)
file.WriteLineToFile("");
file.WriteLineToFile(header(line.group, ssa));
file.WriteLineToFile(format(line.group, ssa), false);
file.WriteLineToFile(line.GroupHeader(ssa));
file.WriteLineToFile(format(line.Group(), ssa), false);
group = line.group;
group = line.Group();
}
file.WriteLineToFile(ssa ? line.GetSSAText() : line.GetEntryData());