Make AssEntry purely a base class and add AssInfo

Now that all the other junk is being dropped from the file, script info
lines are the only thing left which was a concrete AssEntry, and
AssEntry wasn't actually a very good way to store them.
This commit is contained in:
Thomas Goyne 2012-12-07 18:51:09 -08:00
parent cccd95941d
commit 9b44f92235
13 changed files with 95 additions and 116 deletions

View file

@ -256,6 +256,7 @@
<ClInclude Include="$(SrcDir)visual_tool_rotatez.h" /> <ClInclude Include="$(SrcDir)visual_tool_rotatez.h" />
<ClInclude Include="$(SrcDir)visual_tool_scale.h" /> <ClInclude Include="$(SrcDir)visual_tool_scale.h" />
<ClInclude Include="$(SrcDir)visual_tool_vector_clip.h" /> <ClInclude Include="$(SrcDir)visual_tool_vector_clip.h" />
<ClInclude Include="$(SrcDir)ass_info.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="$(SrcDir)aegisublocale.cpp" /> <ClCompile Include="$(SrcDir)aegisublocale.cpp" />

View file

@ -684,6 +684,10 @@
<ClInclude Include="$(SrcDir)dialog_autosave.h"> <ClInclude Include="$(SrcDir)dialog_autosave.h">
<Filter>Features\Autosave</Filter> <Filter>Features\Autosave</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SrcDir)include\aegisub\hotkey.h" />
<ClInclude Include="$(SrcDir)ass_info.h">
<Filter>ASS</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="$(SrcDir)ass_dialogue.cpp"> <ClCompile Include="$(SrcDir)ass_dialogue.cpp">

View file

@ -46,8 +46,7 @@
#include <libaegisub/scoped_ptr.h> #include <libaegisub/scoped_ptr.h>
AssAttachment::AssAttachment(wxString const& name, AssEntryGroup group) AssAttachment::AssAttachment(wxString const& name, AssEntryGroup group)
: AssEntry(wxString()) : data(new std::vector<char>)
, data(new std::vector<char>)
, filename(name) , filename(name)
, group(group) , group(group)
{ {

View file

@ -55,8 +55,7 @@ std::size_t hash_value(wxString const& s) {
} }
AssDialogue::AssDialogue() AssDialogue::AssDialogue()
: AssEntry(wxString()) : Comment(false)
, Comment(false)
, Layer(0) , Layer(0)
, Start(0) , Start(0)
, End(5000) , End(5000)
@ -66,8 +65,7 @@ AssDialogue::AssDialogue()
} }
AssDialogue::AssDialogue(AssDialogue const& that) AssDialogue::AssDialogue(AssDialogue const& that)
: AssEntry(wxString()) : Comment(that.Comment)
, Comment(that.Comment)
, Layer(that.Layer) , Layer(that.Layer)
, Start(that.Start) , Start(that.Start)
, End(that.End) , End(that.End)
@ -80,8 +78,7 @@ AssDialogue::AssDialogue(AssDialogue const& that)
} }
AssDialogue::AssDialogue(wxString const& data) AssDialogue::AssDialogue(wxString const& data)
: AssEntry(wxString()) : Comment(false)
, Comment(false)
, Layer(0) , Layer(0)
, Start(0) , Start(0)
, End(5000) , End(5000)

View file

@ -163,8 +163,6 @@ public:
/// Update the text of the line from parsed blocks /// Update the text of the line from parsed blocks
void UpdateText(boost::ptr_vector<AssDialogueBlock>& blocks); void UpdateText(boost::ptr_vector<AssDialogueBlock>& blocks);
const wxString GetEntryData() const override; const wxString GetEntryData() const override;
/// Do nothing
void SetEntryData(wxString const&) override { }
template<int which> template<int which>
void SetMarginString(wxString const& value) { SetMarginString(value, which);} void SetMarginString(wxString const& value) { SetMarginString(value, which);}

View file

@ -1,29 +1,16 @@
// Copyright (c) 2005, Rodrigo Braz Monteiro // Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
// All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Permission to use, copy, modify, and distribute this software for any
// modification, are permitted provided that the following conditions are met: // purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
// //
// * Redistributions of source code must retain the above copyright notice, // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// this list of conditions and the following disclaimer. // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// * Redistributions in binary form must reproduce the above copyright notice, // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// this list of conditions and the following disclaimer in the documentation // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// and/or other materials provided with the distribution. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// * Neither the name of the Aegisub Group nor the names of its contributors // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// may be used to endorse or promote products derived from this software // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// //
// Aegisub Project http://www.aegisub.org/ // Aegisub Project http://www.aegisub.org/
@ -36,15 +23,6 @@
#include "ass_entry.h" #include "ass_entry.h"
wxString AssEntry::GetSSAText() const {
if (data.Lower() == "scripttype: v4.00+") return "ScriptType: v4.00";
return GetEntryData();
}
AssEntry *AssEntry::Clone() const {
return new AssEntry(data);
}
wxString const& AssEntry::GroupHeader(bool ssa) const { wxString const& AssEntry::GroupHeader(bool ssa) const {
static wxString ass_headers[] = { static wxString ass_headers[] = {
"[Script Info]", "[Script Info]",

View file

@ -48,29 +48,21 @@ enum AssEntryGroup {
}; };
class AssEntry : public boost::intrusive::make_list_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink> >::type { class AssEntry : public boost::intrusive::make_list_base_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink> >::type {
/// Raw data, exactly the same line that appears on the .ass (note that this will be in ass even if source wasn't)
wxString data;
public: public:
AssEntry(wxString const& data) : data(data) { }
virtual ~AssEntry() { } virtual ~AssEntry() { }
/// Create a copy of this entry /// Create a copy of this entry
virtual AssEntry *Clone() const; virtual AssEntry *Clone() const=0;
/// Section of the file this entry belongs to /// Section of the file this entry belongs to
virtual AssEntryGroup Group() const { return ENTRY_INFO; } virtual AssEntryGroup Group() const=0;
/// ASS or SSA Section header for this entry's group /// ASS or SSA Section header for this entry's group
wxString const& GroupHeader(bool ssa=false) const; wxString const& GroupHeader(bool ssa=false) const;
/// @brief Get this line's raw entry data in ASS format /// @brief Get this line's raw entry data in ASS format
virtual const wxString GetEntryData() const { return data; } virtual const wxString GetEntryData() const=0;
/// @brief Set this line's raw entry data
/// @param newData New raw entry data
virtual void SetEntryData(wxString const& newData) { data = newData; }
/// Get this line in SSA format /// Get this line in SSA format
virtual wxString GetSSAText() const; virtual wxString GetSSAText() const { return GetEntryData(); }
}; };

View file

@ -46,6 +46,7 @@
#include "ass_attachment.h" #include "ass_attachment.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_info.h"
#include "ass_override.h" #include "ass_override.h"
#include "ass_style.h" #include "ass_style.h"
#include "compat.h" #include "compat.h"
@ -218,16 +219,16 @@ void AssFile::LoadDefault(bool defline) {
Clear(); Clear();
// Write headers // Write headers
Line.push_back(*new AssEntry("Title: Default Aegisub file")); Line.push_back(*new AssInfo("Title", "Default Aegisub file"));
Line.push_back(*new AssEntry("ScriptType: v4.00+")); Line.push_back(*new AssInfo("ScriptType", "v4.00+"));
Line.push_back(*new AssEntry("WrapStyle: 0")); Line.push_back(*new AssInfo("WrapStyle", "0"));
Line.push_back(*new AssEntry("ScaledBorderAndShadow: yes")); Line.push_back(*new AssInfo("ScaledBorderAndShadow", "yes"));
Line.push_back(*new AssEntry("Collisions: Normal")); Line.push_back(*new AssInfo("Collisions", "Normal"));
if (!OPT_GET("Subtitle/Default Resolution/Auto")->GetBool()) { if (!OPT_GET("Subtitle/Default Resolution/Auto")->GetBool()) {
Line.push_back(*new AssEntry(wxString::Format("PlayResX: %" PRId64, OPT_GET("Subtitle/Default Resolution/Width")->GetInt()))); Line.push_back(*new AssInfo("PlayResX", wxString::Format("%" 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 AssInfo("PlayResY", wxString::Format("%" PRId64, OPT_GET("Subtitle/Default Resolution/Height")->GetInt())));
} }
Line.push_back(*new AssEntry("YCbCr Matrix: None")); Line.push_back(*new AssInfo("YCbCr Matrix", "None"));
Line.push_back(*new AssStyle); Line.push_back(*new AssStyle);
@ -263,7 +264,7 @@ AssFile& AssFile::operator=(AssFile from) {
return *this; return *this;
} }
void AssFile::InsertLine( AssEntry *entry) { void AssFile::InsertLine(AssEntry *entry) {
if (Line.empty()) { if (Line.empty()) {
Line.push_back(*entry); Line.push_back(*entry);
return; return;
@ -297,17 +298,10 @@ void AssFile::InsertAttachment(wxString filename) {
wxString AssFile::GetScriptInfo(wxString key) const { wxString AssFile::GetScriptInfo(wxString key) const {
key.MakeLower(); key.MakeLower();
key += ":";
bool GotIn = false;
for (auto const& line : Line) { for (const auto info : Line | agi::of_type<AssInfo>()) {
if (line.Group() == ENTRY_INFO) { if (key == info->Key().Lower())
GotIn = true; return info->Value();
wxString curText = line.GetEntryData();
if (curText.Lower().StartsWith(key))
return curText.Mid(key.size()).Trim(true).Trim(false);
}
else if (GotIn) return "";
} }
return ""; return "";
@ -320,40 +314,18 @@ int AssFile::GetScriptInfoAsInt(wxString const& key) const {
} }
void AssFile::SetScriptInfo(wxString const& key, wxString const& value) { void AssFile::SetScriptInfo(wxString const& key, wxString const& value) {
wxString search_key = key.Lower() + ":"; wxString lower_key = key.Lower();
size_t key_size = search_key.size(); for (auto info : Line | agi::of_type<AssInfo>()) {
entryIter script_info_end; if (lower_key == info->Key().Lower()) {
bool found_script_info = false; if (value.empty())
delete info;
for (auto& line : Line) { else
if (line.Group() == ENTRY_INFO) { info->SetValue(value);
found_script_info = true;
wxString cur_text = line.GetEntryData().Left(key_size).Lower();
if (cur_text == search_key) {
if (value.empty())
delete &line;
else
line.SetEntryData(key + ": " + value);
return;
}
script_info_end = Line.iterator_to(line);
}
else if (found_script_info) {
if (value.size())
Line.insert(script_info_end, *new AssEntry(key + ": " + value));
return; return;
} }
} }
// Found a script info section, but not this key or anything after it, InsertLine(new AssInfo(key, value));
// so add it at the end of the file
if (found_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));
}
} }
void AssFile::GetResolution(int &sw,int &sh) const { void AssFile::GetResolution(int &sw,int &sh) const {

36
aegisub/src/ass_info.h Normal file
View file

@ -0,0 +1,36 @@
// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// Aegisub Project http://www.aegisub.org/
#include "ass_entry.h"
class AssInfo : public AssEntry {
wxString key;
wxString value;
public:
AssInfo(AssInfo const& o) : key(o.key), value(o.value) { }
AssInfo(wxString const& line) : key(line.BeforeFirst(':').Trim()), value(line.AfterFirst(':').Trim(false)) { }
AssInfo(wxString const& key, wxString const& value) : key(key), value(value) { }
AssEntry *Clone() const override { return new AssInfo(*this); }
AssEntryGroup Group() const override { return ENTRY_INFO; }
const wxString GetEntryData() const override { return key + ":" + value; }
wxString GetSSAText() const override { return key.Lower() == "scripttype: v4.00+" ? "ScriptType: v4.00" : GetEntryData(); }
wxString Key() const { return key; }
wxString Value() const { return value; }
void SetValue(wxString const& new_value) { value = new_value; }
};

View file

@ -19,6 +19,7 @@
#include "ass_attachment.h" #include "ass_attachment.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_info.h"
#include "ass_style.h" #include "ass_style.h"
#include "subtitle_format.h" #include "subtitle_format.h"
@ -88,7 +89,7 @@ void AssParser::ParseScriptInfoLine(wxString const& data) {
} }
} }
InsertLine(new AssEntry(data)); InsertLine(new AssInfo(data));
} }
void AssParser::ParseEventLine(wxString const& data) { void AssParser::ParseEventLine(wxString const& data) {

View file

@ -45,8 +45,7 @@
#include "utils.h" #include "utils.h"
AssStyle::AssStyle() AssStyle::AssStyle()
: AssEntry(wxString()) : name("Default")
, name("Default")
, font("Arial") , font("Arial")
, fontsize(20.) , fontsize(20.)
, primary(255, 255, 255) , primary(255, 255, 255)
@ -89,9 +88,7 @@ static double get_next_double(wxStringTokenizer &tok) {
return temp; return temp;
} }
AssStyle::AssStyle(wxString rawData, int version) AssStyle::AssStyle(wxString rawData, int version) {
: AssEntry(wxString())
{
wxStringTokenizer tkn(rawData.Trim(false).Mid(6), ",", wxTOKEN_RET_EMPTY_ALL); wxStringTokenizer tkn(rawData.Trim(false).Mid(6), ",", wxTOKEN_RET_EMPTY_ALL);
name = get_next_string(tkn).Trim(true).Trim(false); name = get_next_string(tkn).Trim(true).Trim(false);
@ -173,7 +170,7 @@ void AssStyle::UpdateData() {
name.Replace(",", ";"); name.Replace(",", ";");
font.Replace(",", ";"); font.Replace(",", ";");
SetEntryData(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", data = 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, name, font, fontsize,
primary.GetAssStyleFormatted(), primary.GetAssStyleFormatted(),
secondary.GetAssStyleFormatted(), secondary.GetAssStyleFormatted(),
@ -183,7 +180,7 @@ void AssStyle::UpdateData() {
(underline?-1:0),(strikeout?-1:0), (underline?-1:0),(strikeout?-1:0),
scalex,scaley,spacing,angle, scalex,scaley,spacing,angle,
borderstyle,outline_w,shadow_w,alignment, borderstyle,outline_w,shadow_w,alignment,
Margin[0],Margin[1],Margin[2],encoding)); Margin[0],Margin[1],Margin[2],encoding);
} }
wxString AssStyle::GetSSAText() const { wxString AssStyle::GetSSAText() const {

View file

@ -41,6 +41,8 @@
#include <libaegisub/color.h> #include <libaegisub/color.h>
class AssStyle : public AssEntry { class AssStyle : public AssEntry {
wxString data;
public: public:
wxString name; ///< Name of the style; must be case-insensitively unique within a file despite being case-sensitive wxString name; ///< Name of the style; must be case-insensitively unique within a file despite being case-sensitive
wxString font; ///< Font face name wxString font; ///< Font face name
@ -76,6 +78,7 @@ public:
AssStyle(); AssStyle();
AssStyle(wxString data, int version=1); AssStyle(wxString data, int version=1);
const wxString GetEntryData() const override { return data; }
wxString GetSSAText() const override; wxString GetSSAText() const override;
AssEntryGroup Group() const override { return ENTRY_STYLE; } AssEntryGroup Group() const override { return ENTRY_STYLE; }
AssEntry *Clone() const override; AssEntry *Clone() const override;

View file

@ -49,6 +49,7 @@
#include <libaegisub/scoped_ptr.h> #include <libaegisub/scoped_ptr.h>
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "ass_info.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_karaoke.h" #include "ass_karaoke.h"
#include "ass_override.h" #include "ass_override.h"
@ -203,9 +204,9 @@ namespace Automation4 {
set_field(L, "section", e->GroupHeader()); set_field(L, "section", e->GroupHeader());
set_field(L, "raw", raw); set_field(L, "raw", raw);
if (e->Group() == ENTRY_INFO) { if (AssInfo *info = dynamic_cast<AssInfo*>(e)) {
set_field(L, "key", raw.BeforeFirst(':')); set_field(L, "key", info->Key());
set_field(L, "value", raw.AfterFirst(':')); set_field(L, "value", info->Value());
set_field(L, "class", "info"); set_field(L, "class", "info");
} }
else if (AssDialogue *dia = dynamic_cast<AssDialogue*>(e)) { else if (AssDialogue *dia = dynamic_cast<AssDialogue*>(e)) {
@ -297,7 +298,7 @@ namespace Automation4 {
wxString section = get_wxstring_field(L, "section", "common"); wxString section = get_wxstring_field(L, "section", "common");
if (lclass == "info") { if (lclass == "info") {
result = new AssEntry(wxString::Format("%s: %s", get_wxstring_field(L, "key", "info"), get_wxstring_field(L, "value", "info"))); result = new AssInfo(get_wxstring_field(L, "key", "info"), get_wxstring_field(L, "value", "info"));
} }
else if (lclass == "style") { else if (lclass == "style") {
AssStyle *sty = new AssStyle; AssStyle *sty = new AssStyle;