mirror of https://github.com/odrling/Aegisub
Drop format and header lines from the in-memory file representation
They're just pointless cruft, so drop them from the file when parsing and re-add them when saving as ASS or SSA.
This commit is contained in:
parent
30ceced39f
commit
b94547aa71
|
@ -37,15 +37,7 @@
|
||||||
#include "ass_entry.h"
|
#include "ass_entry.h"
|
||||||
|
|
||||||
wxString AssEntry::GetSSAText() const {
|
wxString AssEntry::GetSSAText() const {
|
||||||
wxString lower = data.Lower();
|
if (data.Lower() == "scripttype: v4.00+") return "ScriptType: v4.00";
|
||||||
|
|
||||||
// Special cases
|
|
||||||
if (lower == "[v4+ styles]") return "[V4 Styles]";
|
|
||||||
if (lower == "scripttype: v4.00+") return "ScriptType: v4.00";
|
|
||||||
if (lower.Left(7) == "format:") {
|
|
||||||
if (group.Lower() == "[events]") return "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text";
|
|
||||||
if (group.Lower() == "[v4+ styles]") return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding";
|
|
||||||
}
|
|
||||||
return GetEntryData();
|
return GetEntryData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,9 @@ void AssFile::Load(const wxString &_filename, wxString const& charset) {
|
||||||
|
|
||||||
// And if it doesn't add defaults for each
|
// And if it doesn't add defaults for each
|
||||||
if (!found_style)
|
if (!found_style)
|
||||||
temp.InsertStyle(new AssStyle);
|
temp.InsertLine(new AssStyle);
|
||||||
if (!found_dialogue)
|
if (!found_dialogue)
|
||||||
temp.InsertDialogue(new AssDialogue);
|
temp.InsertLine(new AssDialogue);
|
||||||
|
|
||||||
swap(temp);
|
swap(temp);
|
||||||
}
|
}
|
||||||
|
@ -171,20 +171,29 @@ wxString AssFile::AutoSave() {
|
||||||
return dstpath.GetFullPath();
|
return dstpath.GetFullPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_line(wxString const& line, std::vector<char>& dst) {
|
||||||
|
wxCharBuffer buffer = (line + "\r\n").utf8_str();
|
||||||
|
copy(buffer.data(), buffer.data() + buffer.length(), back_inserter(dst));
|
||||||
|
}
|
||||||
|
|
||||||
void AssFile::SaveMemory(std::vector<char> &dst) {
|
void AssFile::SaveMemory(std::vector<char> &dst) {
|
||||||
// Check if subs contain at least one style
|
// Check if subs contain at least one style
|
||||||
// Add a default style if they don't for compatibility with libass/asa
|
// Add a default style if they don't for compatibility with libass/asa
|
||||||
if (GetStyles().Count() == 0)
|
if (GetStyles().empty())
|
||||||
InsertStyle(new AssStyle);
|
InsertLine(new AssStyle);
|
||||||
|
|
||||||
// Prepare vector
|
// Prepare vector
|
||||||
dst.clear();
|
dst.clear();
|
||||||
dst.reserve(0x4000);
|
dst.reserve(0x4000);
|
||||||
|
|
||||||
// Write file
|
// Write file
|
||||||
|
wxString group;
|
||||||
for (auto const& line : Line) {
|
for (auto const& line : Line) {
|
||||||
wxCharBuffer buffer = (line.GetEntryData() + "\r\n").utf8_str();
|
if (group != line.group) {
|
||||||
copy(buffer.data(), buffer.data() + buffer.length(), back_inserter(dst));
|
group = line.group;
|
||||||
|
write_line(group, dst);
|
||||||
|
}
|
||||||
|
write_line(line.GetEntryData(), dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +220,6 @@ void AssFile::LoadDefault(bool defline) {
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
// Write headers
|
// Write headers
|
||||||
Line.push_back(*new AssEntry("[Script Info]", "[Script Info]"));
|
|
||||||
Line.push_back(*new AssEntry("Title: Default Aegisub file", "[Script Info]"));
|
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("ScriptType: v4.00+", "[Script Info]"));
|
||||||
Line.push_back(*new AssEntry("WrapStyle: 0", "[Script Info]"));
|
Line.push_back(*new AssEntry("WrapStyle: 0", "[Script Info]"));
|
||||||
|
@ -223,10 +231,7 @@ void AssFile::LoadDefault(bool defline) {
|
||||||
}
|
}
|
||||||
Line.push_back(*new AssEntry("YCbCr Matrix: None", "[Script Info]"));
|
Line.push_back(*new AssEntry("YCbCr Matrix: None", "[Script Info]"));
|
||||||
|
|
||||||
InsertStyle(new AssStyle);
|
Line.push_back(*new AssStyle);
|
||||||
|
|
||||||
Line.push_back(*new AssEntry("[Events]", "[Events]"));
|
|
||||||
Line.push_back(*new AssEntry("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", "[Events]"));
|
|
||||||
|
|
||||||
if (defline)
|
if (defline)
|
||||||
Line.push_back(*new AssDialogue);
|
Line.push_back(*new AssDialogue);
|
||||||
|
@ -260,37 +265,23 @@ AssFile& AssFile::operator=(AssFile from) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool try_insert(EntryList &lines, AssEntry *entry) {
|
void AssFile::InsertLine( AssEntry *entry) {
|
||||||
if (lines.empty()) return false;
|
if (Line.empty()) {
|
||||||
|
Line.push_back(*entry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Search for insertion point
|
// Search for insertion point
|
||||||
entryIter it = lines.end();
|
entryIter it = Line.end();
|
||||||
do {
|
do {
|
||||||
--it;
|
--it;
|
||||||
if (it->group == entry->group) {
|
if (it->group == entry->group) {
|
||||||
lines.insert(++it, *entry);
|
Line.insert(++it, *entry);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
} while (it != lines.begin());
|
} while (it != Line.begin());
|
||||||
|
|
||||||
return false;
|
Line.push_back(*entry);
|
||||||
}
|
|
||||||
|
|
||||||
void AssFile::InsertStyle(AssStyle *style) {
|
|
||||||
if (try_insert(Line, style)) return;
|
|
||||||
|
|
||||||
// No styles found, add them
|
|
||||||
Line.push_back(*new AssEntry("[V4+ Styles]", "[V4+ Styles]"));
|
|
||||||
Line.push_back(*new AssEntry("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding", "[V4+ Styles]"));
|
|
||||||
Line.push_back(*style);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssFile::InsertAttachment(AssAttachment *attach) {
|
|
||||||
if (try_insert(Line, attach)) return;
|
|
||||||
|
|
||||||
// Didn't find a group of the appropriate type so create it
|
|
||||||
Line.push_back(*new AssEntry(attach->group, attach->group));
|
|
||||||
Line.push_back(*attach);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssFile::InsertAttachment(wxString filename) {
|
void AssFile::InsertAttachment(wxString filename) {
|
||||||
|
@ -303,16 +294,7 @@ void AssFile::InsertAttachment(wxString filename) {
|
||||||
std::unique_ptr<AssAttachment> newAttach(new AssAttachment(wxFileName(filename).GetFullName(), group));
|
std::unique_ptr<AssAttachment> newAttach(new AssAttachment(wxFileName(filename).GetFullName(), group));
|
||||||
newAttach->Import(filename);
|
newAttach->Import(filename);
|
||||||
|
|
||||||
InsertAttachment(newAttach.release());
|
InsertLine(newAttach.release());
|
||||||
}
|
|
||||||
|
|
||||||
void AssFile::InsertDialogue(AssDialogue *diag) {
|
|
||||||
if (try_insert(Line, diag)) return;
|
|
||||||
|
|
||||||
// Didn't find a group of the appropriate type so create it
|
|
||||||
Line.push_back(*new AssEntry("[Events]", "[Events]"));
|
|
||||||
Line.push_back(*new AssEntry("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", "[Events]"));
|
|
||||||
Line.push_back(*diag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString AssFile::GetScriptInfo(wxString key) const {
|
wxString AssFile::GetScriptInfo(wxString key) const {
|
||||||
|
@ -373,7 +355,6 @@ void AssFile::SetScriptInfo(wxString const& key, wxString const& value) {
|
||||||
// Script info section not found, so add it at the beginning of the file
|
// Script info section not found, so add it at the beginning of the file
|
||||||
else {
|
else {
|
||||||
Line.push_front(*new AssEntry(key + ": " + value, "[Script Info]"));
|
Line.push_front(*new AssEntry(key + ": " + value, "[Script Info]"));
|
||||||
Line.push_front(*new AssEntry("[Script Info]", "[Script Info]"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,14 +102,10 @@ public:
|
||||||
/// @brief Load default file
|
/// @brief Load default file
|
||||||
/// @param defline Add a blank line to the file
|
/// @param defline Add a blank line to the file
|
||||||
void LoadDefault(bool defline=true);
|
void LoadDefault(bool defline=true);
|
||||||
/// Add a style to the file
|
/// Add a line to the file at the end of the appropriate section
|
||||||
void InsertStyle(AssStyle *style);
|
void InsertLine(AssEntry *line);
|
||||||
/// Add an attachment to the file
|
|
||||||
void InsertAttachment(AssAttachment *attach);
|
|
||||||
/// Attach a file to the ass file
|
/// Attach a file to the ass file
|
||||||
void InsertAttachment(wxString filename);
|
void InsertAttachment(wxString filename);
|
||||||
/// Add a dialogue line to the file
|
|
||||||
void InsertDialogue(AssDialogue *diag);
|
|
||||||
/// Get the names of all of the styles available
|
/// Get the names of all of the styles available
|
||||||
wxArrayString GetStyles() const;
|
wxArrayString GetStyles() const;
|
||||||
/// @brief Get a style by name
|
/// @brief Get a style by name
|
||||||
|
|
|
@ -72,10 +72,6 @@ void AssParser::ParseScriptInfoLine(wxString const& data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the first nonblank line isn't a header pretend it starts with [Script Info]
|
|
||||||
if (target->Line.empty())
|
|
||||||
target->Line.push_back(*new AssEntry("[Script Info]", "[Script Info]"));
|
|
||||||
|
|
||||||
if (data.StartsWith("ScriptType:")) {
|
if (data.StartsWith("ScriptType:")) {
|
||||||
wxString versionString = data.Mid(11).Trim(true).Trim(false).Lower();
|
wxString versionString = data.Mid(11).Trim(true).Trim(false).Lower();
|
||||||
int trueVersion;
|
int trueVersion;
|
||||||
|
@ -97,15 +93,11 @@ void AssParser::ParseScriptInfoLine(wxString const& data) {
|
||||||
void AssParser::ParseEventLine(wxString const& data) {
|
void AssParser::ParseEventLine(wxString const& data) {
|
||||||
if (data.StartsWith("Dialogue:") || data.StartsWith("Comment:"))
|
if (data.StartsWith("Dialogue:") || data.StartsWith("Comment:"))
|
||||||
target->Line.push_back(*new AssDialogue(data));
|
target->Line.push_back(*new AssDialogue(data));
|
||||||
else if (data.StartsWith("Format:"))
|
|
||||||
target->Line.push_back(*new AssEntry("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text", "[Events]"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssParser::ParseStyleLine(wxString const& data) {
|
void AssParser::ParseStyleLine(wxString const& data) {
|
||||||
if (data.StartsWith("Style:"))
|
if (data.StartsWith("Style:"))
|
||||||
target->Line.push_back(*new AssStyle(data, version));
|
target->Line.push_back(*new AssStyle(data, version));
|
||||||
else if (data.StartsWith("Format:"))
|
|
||||||
target->Line.push_back(*new AssEntry("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding", "[V4+ Styles]"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssParser::ParseFontLine(wxString const& data) {
|
void AssParser::ParseFontLine(wxString const& data) {
|
||||||
|
@ -150,23 +142,16 @@ void AssParser::AddLine(wxString const& data) {
|
||||||
version = 1;
|
version = 1;
|
||||||
state = &AssParser::ParseStyleLine;
|
state = &AssParser::ParseStyleLine;
|
||||||
}
|
}
|
||||||
else if (low == "[events]") {
|
else if (low == "[events]")
|
||||||
state = &AssParser::ParseEventLine;
|
state = &AssParser::ParseEventLine;
|
||||||
}
|
else if (low == "[script info]")
|
||||||
else if (low == "[script info]") {
|
|
||||||
state = &AssParser::ParseScriptInfoLine;
|
state = &AssParser::ParseScriptInfoLine;
|
||||||
}
|
else if (low == "[graphics]")
|
||||||
else if (low == "[graphics]") {
|
|
||||||
state = &AssParser::ParseGraphicsLine;
|
state = &AssParser::ParseGraphicsLine;
|
||||||
}
|
else if (low == "[fonts]")
|
||||||
else if (low == "[fonts]") {
|
|
||||||
state = &AssParser::ParseFontLine;
|
state = &AssParser::ParseFontLine;
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
state = &AssParser::AppendUnknownLine;
|
state = &AssParser::AppendUnknownLine;
|
||||||
}
|
|
||||||
|
|
||||||
target->Line.push_back(*new AssEntry(header, header));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,23 +213,11 @@ namespace Automation4 {
|
||||||
if (StringEmptyOrWhitespace(raw)) {
|
if (StringEmptyOrWhitespace(raw)) {
|
||||||
set_field(L, "class", "clear");
|
set_field(L, "class", "clear");
|
||||||
}
|
}
|
||||||
else if (raw[0] == ';') {
|
|
||||||
// "text" field, same as "raw" but with semicolon stripped
|
|
||||||
set_field(L, "text", raw.Mid(1));
|
|
||||||
set_field(L, "class", "comment");
|
|
||||||
}
|
|
||||||
else if (raw[0] == '[') {
|
|
||||||
set_field(L, "class", "head");
|
|
||||||
}
|
|
||||||
else if (e->group.Lower() == "[script info]") {
|
else if (e->group.Lower() == "[script info]") {
|
||||||
set_field(L, "key", raw.BeforeFirst(':'));
|
set_field(L, "key", raw.BeforeFirst(':'));
|
||||||
set_field(L, "value", raw.AfterFirst(':'));
|
set_field(L, "value", raw.AfterFirst(':'));
|
||||||
set_field(L, "class", "info");
|
set_field(L, "class", "info");
|
||||||
}
|
}
|
||||||
else if (raw.Left(7).Lower() == "format:") {
|
|
||||||
// TODO: parse the format line; just use a tokenizer
|
|
||||||
set_field(L, "class", "format");
|
|
||||||
}
|
|
||||||
else if (AssDialogue *dia = dynamic_cast<AssDialogue*>(e)) {
|
else if (AssDialogue *dia = dynamic_cast<AssDialogue*>(e)) {
|
||||||
set_field(L, "comment", dia->Comment);
|
set_field(L, "comment", dia->Comment);
|
||||||
|
|
||||||
|
@ -317,20 +305,9 @@ namespace Automation4 {
|
||||||
try {
|
try {
|
||||||
wxString section = get_wxstring_field(L, "section", "common");
|
wxString section = get_wxstring_field(L, "section", "common");
|
||||||
|
|
||||||
if (lclass == "clear")
|
if (lclass == "info") {
|
||||||
result = new AssEntry("", "");
|
|
||||||
else if (lclass == "comment")
|
|
||||||
result = new AssEntry(";" + get_wxstring_field(L, "text", "comment"), section);
|
|
||||||
else if (lclass == "head")
|
|
||||||
result = new AssEntry(section, section);
|
|
||||||
else 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")), "[Script Info]");
|
||||||
}
|
}
|
||||||
else if (lclass == "format") {
|
|
||||||
// ohshi- ...
|
|
||||||
// *FIXME* maybe ignore the actual data and just put some default stuff based on section?
|
|
||||||
result = new AssEntry("Format: Auto4,Is,Broken", section);
|
|
||||||
}
|
|
||||||
else if (lclass == "style") {
|
else if (lclass == "style") {
|
||||||
AssStyle *sty = new AssStyle;
|
AssStyle *sty = new AssStyle;
|
||||||
result = sty;
|
result = sty;
|
||||||
|
@ -559,17 +536,11 @@ namespace Automation4 {
|
||||||
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
|
// The new entry belongs to a group that doesn't exist yet, so
|
||||||
// create it at the end of the file
|
// create it at the end of the file
|
||||||
if (e->GetEntryData() != e->group) {
|
|
||||||
// Add the header if the entry being added isn't a header
|
|
||||||
lines.push_back(new AssEntry(e->group, e->group));
|
|
||||||
}
|
|
||||||
|
|
||||||
lines.push_back(e);
|
lines.push_back(e);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Append the entry to the end of the existing group
|
// Append the entry to the end of the existing group
|
||||||
++it;
|
lines.insert(++it, e);
|
||||||
lines.insert(it, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -528,7 +528,7 @@ static void delete_lines(agi::Context *c, wxString const& commit_message) {
|
||||||
// lines, so make a new one
|
// lines, so make a new one
|
||||||
if (!new_active) {
|
if (!new_active) {
|
||||||
new_active = new AssDialogue;
|
new_active = new AssDialogue;
|
||||||
c->ass->InsertDialogue(new_active);
|
c->ass->InsertLine(new_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->ass->Commit(commit_message, AssFile::COMMIT_DIAG_ADDREM);
|
c->ass->Commit(commit_message, AssFile::COMMIT_DIAG_ADDREM);
|
||||||
|
|
|
@ -142,7 +142,7 @@ void DialogAttachments::AttachFile(wxFileDialog &diag, wxString const& group, wx
|
||||||
delete newAttach;
|
delete newAttach;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ass->InsertAttachment(newAttach);
|
ass->InsertLine(newAttach);
|
||||||
}
|
}
|
||||||
|
|
||||||
ass->Commit(commit_msg, AssFile::COMMIT_ATTACHMENT);
|
ass->Commit(commit_msg, AssFile::COMMIT_ATTACHMENT);
|
||||||
|
@ -211,30 +211,6 @@ void DialogAttachments::OnDelete(wxCommandEvent &) {
|
||||||
i = listView->GetNextSelected(i);
|
i = listView->GetNextSelected(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove empty attachment sections in the file
|
|
||||||
for (entryIter it = ass->Line.begin(); it != ass->Line.end(); ) {
|
|
||||||
if (it->GetType() == ENTRY_BASE && (it->group == "[Fonts]" || it->group == "[Graphics]")) {
|
|
||||||
wxString group = it->group;
|
|
||||||
entryIter header = it;
|
|
||||||
|
|
||||||
bool has_attachments = false;
|
|
||||||
for (++it; it != ass->Line.end() && it->group == group; ++it) {
|
|
||||||
if (it->GetType() == ENTRY_ATTACHMENT) {
|
|
||||||
has_attachments = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Empty group found, delete it
|
|
||||||
if (!has_attachments) {
|
|
||||||
while (header != it)
|
|
||||||
delete &*header++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
ass->Commit(_("remove attachment"), AssFile::COMMIT_ATTACHMENT);
|
ass->Commit(_("remove attachment"), AssFile::COMMIT_ATTACHMENT);
|
||||||
|
|
||||||
UpdateList();
|
UpdateList();
|
||||||
|
|
|
@ -465,7 +465,7 @@ void DialogStyleEditor::Apply(bool apply, bool close) {
|
||||||
if (store)
|
if (store)
|
||||||
store->push_back(style);
|
store->push_back(style);
|
||||||
else
|
else
|
||||||
c->ass->InsertStyle(style);
|
c->ass->InsertLine(style);
|
||||||
is_new = false;
|
is_new = false;
|
||||||
}
|
}
|
||||||
if (!store)
|
if (!store)
|
||||||
|
|
|
@ -445,7 +445,7 @@ void DialogStyleManager::OnCopyToCurrent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addStyle) {
|
if (addStyle) {
|
||||||
c->ass->InsertStyle(new AssStyle(*Store[selections[i]]));
|
c->ass->InsertLine(new AssStyle(*Store[selections[i]]));
|
||||||
copied.push_back(styleName);
|
copied.push_back(styleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,7 +477,7 @@ void DialogStyleManager::CopyToClipboard(wxListBox *list, T const& v) {
|
||||||
void DialogStyleManager::PasteToCurrent() {
|
void DialogStyleManager::PasteToCurrent() {
|
||||||
add_styles(
|
add_styles(
|
||||||
std::bind(&AssFile::GetStyle, c->ass, _1),
|
std::bind(&AssFile::GetStyle, c->ass, _1),
|
||||||
std::bind(&AssFile::InsertStyle, c->ass, _1));
|
std::bind(&AssFile::InsertLine, c->ass, _1));
|
||||||
|
|
||||||
c->ass->Commit(_("style paste"), AssFile::COMMIT_STYLES);
|
c->ass->Commit(_("style paste"), AssFile::COMMIT_STYLES);
|
||||||
}
|
}
|
||||||
|
@ -626,7 +626,7 @@ void DialogStyleManager::OnCurrentImport() {
|
||||||
modified = true;
|
modified = true;
|
||||||
AssStyle *tempStyle = new AssStyle;
|
AssStyle *tempStyle = new AssStyle;
|
||||||
*tempStyle = *temp.GetStyle(styles[sel]);
|
*tempStyle = *temp.GetStyle(styles[sel]);
|
||||||
c->ass->InsertStyle(tempStyle);
|
c->ass->InsertLine(tempStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
|
|
|
@ -60,7 +60,7 @@ SubtitlesPreview::SubtitlesPreview(wxWindow *parent, wxSize size, int winStyle,
|
||||||
SetStyle(*style);
|
SetStyle(*style);
|
||||||
|
|
||||||
subFile->LoadDefault();
|
subFile->LoadDefault();
|
||||||
subFile->InsertStyle(style);
|
subFile->InsertLine(style);
|
||||||
subFile->Line.push_back(*line);
|
subFile->Line.push_back(*line);
|
||||||
|
|
||||||
SetSizeHints(size.GetWidth(), size.GetHeight(), -1, -1);
|
SetSizeHints(size.GetWidth(), size.GetHeight(), -1, -1);
|
||||||
|
|
|
@ -83,6 +83,36 @@ 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]") {
|
||||||
|
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 (ssa)
|
||||||
|
return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding" LINEBREAK;
|
||||||
|
else
|
||||||
|
return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" LINEBREAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxS("");
|
||||||
|
}
|
||||||
|
|
||||||
void AssSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename, wxString const& encoding) const {
|
void AssSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename, wxString const& encoding) const {
|
||||||
TextFileWriter file(filename, encoding);
|
TextFileWriter file(filename, encoding);
|
||||||
|
|
||||||
|
@ -90,15 +120,20 @@ void AssSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
||||||
file.WriteLineToFile("; http://www.aegisub.org/");
|
file.WriteLineToFile("; http://www.aegisub.org/");
|
||||||
|
|
||||||
bool ssa = filename.Right(4).Lower() == ".ssa";
|
bool ssa = filename.Right(4).Lower() == ".ssa";
|
||||||
|
wxString group;
|
||||||
|
|
||||||
wxString group = src->Line.front().group;
|
|
||||||
for (auto const& line : src->Line) {
|
for (auto const& line : src->Line) {
|
||||||
// Add a blank line between each group
|
|
||||||
if (line.group != group) {
|
if (line.group != group) {
|
||||||
|
// Add a blank line between each group
|
||||||
|
if (!group.empty())
|
||||||
file.WriteLineToFile("");
|
file.WriteLineToFile("");
|
||||||
|
|
||||||
|
file.WriteLineToFile(header(line.group, ssa));
|
||||||
|
file.WriteLineToFile(format(line.group, ssa), false);
|
||||||
|
|
||||||
group = line.group;
|
group = line.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.WriteLineToFile(ssa ? line.GetSSAText() : line.GetEntryData(), true);
|
file.WriteLineToFile(ssa ? line.GetSSAText() : line.GetEntryData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue