diff --git a/aegisub/build/libaegisub/libaegisub.vcxproj b/aegisub/build/libaegisub/libaegisub.vcxproj
index a73a35119..a8126c3f9 100644
--- a/aegisub/build/libaegisub/libaegisub.vcxproj
+++ b/aegisub/build/libaegisub/libaegisub.vcxproj
@@ -38,6 +38,7 @@
+
diff --git a/aegisub/build/libaegisub/libaegisub.vcxproj.filters b/aegisub/build/libaegisub/libaegisub.vcxproj.filters
index a73b5aaf7..ff2bba3f6 100644
--- a/aegisub/build/libaegisub/libaegisub.vcxproj.filters
+++ b/aegisub/build/libaegisub/libaegisub.vcxproj.filters
@@ -164,6 +164,9 @@
Header Files
+
+ Header Files
+
diff --git a/aegisub/libaegisub/include/libaegisub/address_of_adaptor.h b/aegisub/libaegisub/include/libaegisub/address_of_adaptor.h
new file mode 100644
index 000000000..1ca2c33f9
--- /dev/null
+++ b/aegisub/libaegisub/include/libaegisub/address_of_adaptor.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2014, Thomas Goyne
+//
+// 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
+
+namespace agi {
+namespace address_of_detail {
+ using namespace boost::adaptors;
+
+ // Tag type to select the operator| overload
+ struct address_of_tag_type { };
+
+ template
+ struct take_address_of {
+ using result_type = typename std::iterator_traits::pointer;
+ using input_type = typename std::iterator_traits::reference;
+
+ result_type operator()(input_type v) const { return &v; }
+ };
+
+ template
+ auto operator|(Rng&& r, address_of_tag_type)
+ -> boost::transformed_range, Rng>
+ {
+ return r | transformed(take_address_of());
+ }
+
+ template
+ auto operator|(Rng& r, address_of_tag_type)
+ -> boost::transformed_range, Rng>
+ {
+ return r | transformed(take_address_of());
+ }
+}
+
+namespace {
+ const auto address_of = address_of_detail::address_of_tag_type{};
+}
+}
diff --git a/aegisub/src/ass_attachment.cpp b/aegisub/src/ass_attachment.cpp
index a5b06dfb7..e0c482c84 100644
--- a/aegisub/src/ass_attachment.cpp
+++ b/aegisub/src/ass_attachment.cpp
@@ -59,14 +59,6 @@ AssAttachment::AssAttachment(agi::fs::path const& name, AssEntryGroup group)
entry_data = entry_data.get() + agi::ass::UUEncode(data);
}
-AssEntry *AssAttachment::Clone() const {
- return new AssAttachment(*this);
-}
-
-const std::string AssAttachment::GetEntryData() const {
- return entry_data;
-}
-
size_t AssAttachment::GetSize() const {
auto header_end = entry_data.get().find('\n');
return entry_data.get().size() - header_end - 1;
diff --git a/aegisub/src/ass_attachment.h b/aegisub/src/ass_attachment.h
index 142b01441..ebbad86a6 100644
--- a/aegisub/src/ass_attachment.h
+++ b/aegisub/src/ass_attachment.h
@@ -46,9 +46,9 @@ public:
/// @param raw If false, remove the SSA filename mangling
std::string GetFileName(bool raw=false) const;
- const std::string GetEntryData() const override;
+ const std::string GetEntryData() const override { return entry_data; }
AssEntryGroup Group() const override { return group; }
- AssEntry *Clone() const override;
+ AssAttachment *Clone() const override { return new AssAttachment(*this); }
AssAttachment(AssAttachment const& rgt);
AssAttachment(std::string const& header, AssEntryGroup group);
diff --git a/aegisub/src/ass_dialogue.cpp b/aegisub/src/ass_dialogue.cpp
index 6954fb974..f75298d04 100644
--- a/aegisub/src/ass_dialogue.cpp
+++ b/aegisub/src/ass_dialogue.cpp
@@ -256,7 +256,7 @@ std::string AssDialogue::GetStrippedText() const {
return join(blocks | agi::of_type() | transformed(get_text_p), "");
}
-AssEntry *AssDialogue::Clone() const {
+AssDialogue *AssDialogue::Clone() const {
auto clone = new AssDialogue(*this);
clone->Id = Id;
return clone;
diff --git a/aegisub/src/ass_dialogue.h b/aegisub/src/ass_dialogue.h
index 56af7cacc..780553ba8 100644
--- a/aegisub/src/ass_dialogue.h
+++ b/aegisub/src/ass_dialogue.h
@@ -177,7 +177,7 @@ public:
/// Does this line collide with the passed line?
bool CollidesWith(const AssDialogue *target) const;
- AssEntry *Clone() const override;
+ AssDialogue *Clone() const override;
AssDialogue();
AssDialogue(AssDialogue const&);
diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp
index 90671e469..0e76725b1 100644
--- a/aegisub/src/ass_file.cpp
+++ b/aegisub/src/ass_file.cpp
@@ -1,36 +1,19 @@
-// Copyright (c) 2005, Rodrigo Braz Monteiro
-// All rights reserved.
+// Copyright (c) 2014, Thomas Goyne
//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
+// 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.
//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of the Aegisub Group nor the names of its contributors
-// may be used to endorse or promote products derived from 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.
+// 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/
-/// @file ass_file.cpp
-/// @brief Overall storage of subtitle files, undo management and more
-/// @ingroup subs_storage
-
#include "config.h"
#include "ass_file.h"
@@ -42,20 +25,20 @@
#include "options.h"
#include "utils.h"
-#include
-
#include
#include
#include
+AssFile::AssFile() { }
+
AssFile::~AssFile() {
- Info.clear_and_dispose([](AssEntry *e) { delete e; });
- Styles.clear_and_dispose([](AssEntry *e) { delete e; });
- Events.clear_and_dispose([](AssEntry *e) { delete e; });
- Attachments.clear_and_dispose([](AssEntry *e) { delete e; });
+ Info.clear_and_dispose([](AssInfo *e) { delete e; });
+ Styles.clear_and_dispose([](AssStyle *e) { delete e; });
+ Events.clear_and_dispose([](AssDialogue *e) { delete e; });
+ Attachments.clear_and_dispose([](AssAttachment *e) { delete e; });
}
-void AssFile::LoadDefault(bool defline) {
+void AssFile::LoadDefault(bool include_dialogue_line) {
Info.push_back(*new AssInfo("Title", "Default Aegisub file"));
Info.push_back(*new AssInfo("ScriptType", "v4.00+"));
Info.push_back(*new AssInfo("WrapStyle", "0"));
@@ -68,15 +51,15 @@ void AssFile::LoadDefault(bool defline) {
Styles.push_back(*new AssStyle);
- if (defline)
+ if (include_dialogue_line)
Events.push_back(*new AssDialogue);
}
AssFile::AssFile(const AssFile &from) {
- Info.clone_from(from.Info, std::mem_fun_ref(&AssEntry::Clone), [](AssEntry *e) { delete e; });
- Styles.clone_from(from.Styles, std::mem_fun_ref(&AssEntry::Clone), [](AssEntry *e) { delete e; });
- Events.clone_from(from.Events, std::mem_fun_ref(&AssEntry::Clone), [](AssEntry *e) { delete e; });
- Attachments.clone_from(from.Attachments, std::mem_fun_ref(&AssEntry::Clone), [](AssEntry *e) { delete e; });
+ Info.clone_from(from.Info, std::mem_fun_ref(&AssInfo::Clone), [](AssInfo *e) { delete e; });
+ Styles.clone_from(from.Styles, std::mem_fun_ref(&AssStyle::Clone), [](AssStyle *e) { delete e; });
+ Events.clone_from(from.Events, std::mem_fun_ref(&AssDialogue::Clone), [](AssDialogue *e) { delete e; });
+ Attachments.clone_from(from.Attachments, std::mem_fun_ref(&AssAttachment::Clone), [](AssAttachment *e) { delete e; });
}
void AssFile::swap(AssFile& from) throw() {
@@ -102,9 +85,9 @@ void AssFile::InsertAttachment(agi::fs::path const& filename) {
}
std::string AssFile::GetScriptInfo(std::string const& key) const {
- for (const auto info : Info | agi::of_type()) {
- if (boost::iequals(key, info->Key()))
- return info->Value();
+ for (auto const& info : Info) {
+ if (boost::iequals(key, info.Key()))
+ return info.Value();
}
return "";
@@ -131,12 +114,12 @@ void AssFile::SaveUIState(std::string const& key, std::string const& value) {
}
void AssFile::SetScriptInfo(std::string const& key, std::string const& value) {
- for (auto info : Info | agi::of_type()) {
- if (boost::iequals(key, info->Key())) {
+ for (auto& info : Info) {
+ if (boost::iequals(key, info.Key())) {
if (value.empty())
- delete info;
+ delete &info;
else
- info->SetValue(value);
+ info.SetValue(value);
return;
}
}
@@ -145,47 +128,42 @@ void AssFile::SetScriptInfo(std::string const& key, std::string const& value) {
Info.push_back(*new AssInfo(key, value));
}
-void AssFile::GetResolution(int &sw,int &sh) const {
+void AssFile::GetResolution(int &sw, int &sh) const {
sw = GetScriptInfoAsInt("PlayResX");
sh = GetScriptInfoAsInt("PlayResY");
- // Gabest logic?
+ // Gabest logic: default is 384x288, assume 1280x1024 if either height or
+ // width are that, otherwise assume 4:3 if only heigh or width are set.
+ // Why 1280x1024? Who the fuck knows. Clearly just Gabest trolling everyone.
if (sw == 0 && sh == 0) {
sw = 384;
sh = 288;
- } else if (sw == 0) {
- if (sh == 1024)
- sw = 1280;
- else
- sw = sh * 4 / 3;
- } else if (sh == 0) {
- // you are not crazy; this doesn't make any sense
- if (sw == 1280)
- sh = 1024;
- else
- sh = sw * 3 / 4;
}
+ else if (sw == 0)
+ sw = sh == 1024 ? 1280 : sh * 4 / 3;
+ else if (sh == 0)
+ sh = sw == 1280 ? 1024 : sw * 3 / 4;
}
std::vector AssFile::GetStyles() const {
std::vector styles;
- for (auto style : Styles | agi::of_type())
- styles.push_back(style->name);
+ for (auto& style : Styles)
+ styles.push_back(style.name);
return styles;
}
AssStyle *AssFile::GetStyle(std::string const& name) {
- for (auto style : Styles | agi::of_type()) {
- if (boost::iequals(style->name, name))
- return style;
+ for (auto& style : Styles) {
+ if (boost::iequals(style.name, name))
+ return &style;
}
return nullptr;
}
-int AssFile::Commit(wxString const& desc, int type, int amend_id, AssEntry *single_line) {
+int AssFile::Commit(wxString const& desc, int type, int amend_id, AssDialogue *single_line) {
PushState({desc, &amend_id, single_line});
- std::set changed_lines;
+ std::set changed_lines;
if (single_line)
changed_lines.insert(single_line);
@@ -194,50 +172,45 @@ int AssFile::Commit(wxString const& desc, int type, int amend_id, AssEntry *sing
return amend_id;
}
-bool AssFile::CompStart(const AssDialogue* lft, const AssDialogue* rgt) {
- return lft->Start < rgt->Start;
+bool AssFile::CompStart(AssDialogue const& lft, AssDialogue const& rgt) {
+ return lft.Start < rgt.Start;
}
-bool AssFile::CompEnd(const AssDialogue* lft, const AssDialogue* rgt) {
- return lft->End < rgt->End;
+bool AssFile::CompEnd(AssDialogue const& lft, AssDialogue const& rgt) {
+ return lft.End < rgt.End;
}
-bool AssFile::CompStyle(const AssDialogue* lft, const AssDialogue* rgt) {
- return lft->Style < rgt->Style;
+bool AssFile::CompStyle(AssDialogue const& lft, AssDialogue const& rgt) {
+ return lft.Style < rgt.Style;
}
-bool AssFile::CompActor(const AssDialogue* lft, const AssDialogue* rgt) {
- return lft->Actor < rgt->Actor;
+bool AssFile::CompActor(AssDialogue const& lft, AssDialogue const& rgt) {
+ return lft.Actor < rgt.Actor;
}
-bool AssFile::CompEffect(const AssDialogue* lft, const AssDialogue* rgt) {
- return lft->Effect < rgt->Effect;
+bool AssFile::CompEffect(AssDialogue const& lft, AssDialogue const& rgt) {
+ return lft.Effect < rgt.Effect;
}
-bool AssFile::CompLayer(const AssDialogue* lft, const AssDialogue* rgt) {
- return lft->Layer < rgt->Layer;
+bool AssFile::CompLayer(AssDialogue const& lft, AssDialogue const& rgt) {
+ return lft.Layer < rgt.Layer;
}
void AssFile::Sort(CompFunc comp, std::set const& limit) {
Sort(Events, comp, limit);
}
-namespace {
- inline bool is_dialogue(AssEntry *e, std::set const& limit) {
- AssDialogue *d = dynamic_cast(e);
- return d && (limit.empty() || limit.count(d));
+
+void AssFile::Sort(EntryList &lst, CompFunc comp, std::set const& limit) {
+ if (limit.empty()) {
+ lst.sort(comp);
+ return;
}
-}
-void AssFile::Sort(EntryList &lst, CompFunc comp, std::set const& limit) {
- auto compE = [&](AssEntry const& a, AssEntry const& b) {
- return comp(static_cast(&a), static_cast(&b));
- };
+ // Sort each selected block separately, leaving everything else untouched
+ for (auto begin = lst.begin(); begin != lst.end(); ++begin) {
+ if (!limit.count(&*begin)) continue;
+ auto end = begin;
+ while (end != lst.end() && limit.count(&*end)) ++end;
- // Sort each block of AssDialogues separately, leaving everything else untouched
- for (entryIter begin = lst.begin(); begin != lst.end(); ++begin) {
- if (!is_dialogue(&*begin, limit)) continue;
- entryIter end = begin;
- while (end != lst.end() && is_dialogue(&*end, limit)) ++end;
-
- // used instead of std::list::sort for partial list sorting
- EntryList tmp;
+ // sort doesn't support only sorting a sublist, so move them to a temp list
+ EntryList tmp;
tmp.splice(tmp.begin(), lst, begin, end);
- tmp.sort(compE);
+ tmp.sort(comp);
lst.splice(end, tmp);
begin = --end;
diff --git a/aegisub/src/ass_file.h b/aegisub/src/ass_file.h
index dd36272e5..207d4a271 100644
--- a/aegisub/src/ass_file.h
+++ b/aegisub/src/ass_file.h
@@ -41,33 +41,36 @@
#include
#include
-class AssDialogue;
-class AssStyle;
class AssAttachment;
+class AssDialogue;
+class AssInfo;
+class AssStyle;
class wxString;
-typedef boost::intrusive::make_list>::type EntryList;
-typedef EntryList::iterator entryIter;
-typedef EntryList::const_iterator constEntryIter;
+template
+using EntryList = typename boost::intrusive::make_list, boost::intrusive::base_hook>::type;
+
+template
+using EntryIter = typename EntryList::iterator;
struct AssFileCommit {
wxString const& message;
int *commit_id;
- AssEntry *single_line;
+ AssDialogue *single_line;
};
class AssFile {
/// A set of changes has been committed to the file (AssFile::COMMITType)
- agi::signal::Signal const&> AnnounceCommit;
+ agi::signal::Signal const&> AnnounceCommit;
agi::signal::Signal PushState;
public:
/// The lines in the file
- EntryList Info;
- EntryList Styles;
- EntryList Events;
- EntryList Attachments;
+ EntryList Info;
+ EntryList Styles;
+ EntryList Events;
+ EntryList Attachments;
- AssFile() { }
+ AssFile();
AssFile(const AssFile &from);
AssFile& operator=(AssFile from);
~AssFile();
@@ -139,23 +142,23 @@ public:
/// @param commitId Commit to amend rather than pushing a new commit
/// @param single_line Line which was changed, if only one line was
/// @return Unique identifier for the new undo group
- int Commit(wxString const& desc, int type, int commitId = -1, AssEntry *single_line = nullptr);
+ int Commit(wxString const& desc, int type, int commitId = -1, AssDialogue *single_line = nullptr);
/// Comparison function for use when sorting
- typedef bool (*CompFunc)(const AssDialogue* lft, const AssDialogue* rgt);
+ typedef bool (*CompFunc)(AssDialogue const& lft, AssDialogue const& rgt);
/// Compare based on start time
- static bool CompStart(const AssDialogue* lft, const AssDialogue* rgt);
+ static bool CompStart(AssDialogue const& lft, AssDialogue const& rgt);
/// Compare based on end time
- static bool CompEnd(const AssDialogue* lft, const AssDialogue* rgt);
+ static bool CompEnd(AssDialogue const& lft, AssDialogue const& rgt);
/// Compare based on style name
- static bool CompStyle(const AssDialogue* lft, const AssDialogue* rgt);
+ static bool CompStyle(AssDialogue const& lft, AssDialogue const& rgt);
/// Compare based on actor name
- static bool CompActor(const AssDialogue* lft, const AssDialogue* rgt);
+ static bool CompActor(AssDialogue const& lft, AssDialogue const& rgt);
/// Compare based on effect
- static bool CompEffect(const AssDialogue* lft, const AssDialogue* rgt);
+ static bool CompEffect(AssDialogue const& lft, AssDialogue const& rgt);
/// Compare based on layer
- static bool CompLayer(const AssDialogue* lft, const AssDialogue* rgt);
+ static bool CompLayer(AssDialogue const& lft, AssDialogue const& rgt);
/// @brief Sort the dialogue lines in this file
/// @param comp Comparison function to use. Defaults to sorting by start time.
@@ -164,5 +167,5 @@ public:
/// @brief Sort the dialogue lines in the given list
/// @param comp Comparison function to use. Defaults to sorting by start time.
/// @param limit If non-empty, only lines in this set are sorted
- static void Sort(EntryList& lst, CompFunc comp = CompStart, std::set const& limit = std::set());
+ static void Sort(EntryList& lst, CompFunc comp = CompStart, std::set const& limit = std::set());
};
diff --git a/aegisub/src/ass_info.h b/aegisub/src/ass_info.h
index acededc66..07d3998df 100644
--- a/aegisub/src/ass_info.h
+++ b/aegisub/src/ass_info.h
@@ -26,7 +26,7 @@ public:
AssInfo(AssInfo const& o) = default;
AssInfo(std::string key, std::string value) : key(std::move(key)), value(std::move(value)) { }
- AssEntry *Clone() const override { return new AssInfo(*this); }
+ AssInfo *Clone() const override { return new AssInfo(*this); }
AssEntryGroup Group() const override { return AssEntryGroup::INFO; }
const std::string GetEntryData() const override { return key + ": " + value; }
std::string GetSSAText() const override { return boost::iequals(key, "scripttype: v4.00+") ? "ScriptType: v4.00" : GetEntryData(); }
diff --git a/aegisub/src/ass_karaoke.cpp b/aegisub/src/ass_karaoke.cpp
index 9181d78e0..f9303395c 100644
--- a/aegisub/src/ass_karaoke.cpp
+++ b/aegisub/src/ass_karaoke.cpp
@@ -280,19 +280,18 @@ void AssKaraoke::SplitLines(std::set const& lines, agi::Context *c
SubtitleSelection sel = c->selectionController->GetSelectedSet();
bool did_split = false;
- for (entryIter it = c->ass->Events.begin(); it != c->ass->Events.end(); ++it) {
- AssDialogue *diag = dynamic_cast(&*it);
- if (!diag || !lines.count(diag)) continue;
+ for (auto it = c->ass->Events.begin(); it != c->ass->Events.end(); ++it) {
+ if (!lines.count(&*it)) continue;
- kara.SetLine(diag);
+ kara.SetLine(&*it);
// If there aren't at least two tags there's nothing to split
if (kara.size() < 2) continue;
- bool in_sel = sel.count(diag) > 0;
+ bool in_sel = sel.count(&*it) > 0;
for (auto const& syl : kara) {
- auto new_line = new AssDialogue(*diag);
+ auto new_line = new AssDialogue(*it);
new_line->Start = syl.start_time;
new_line->End = syl.start_time + syl.duration;
@@ -305,8 +304,8 @@ void AssKaraoke::SplitLines(std::set const& lines, agi::Context *c
}
--it; // Move `it` to the last of the new lines
- sel.erase(diag);
- delete diag;
+ sel.erase(&*it);
+ delete &*it;
did_split = true;
}
diff --git a/aegisub/src/ass_style.cpp b/aegisub/src/ass_style.cpp
index 88f551929..0b9216a9d 100644
--- a/aegisub/src/ass_style.cpp
+++ b/aegisub/src/ass_style.cpp
@@ -204,10 +204,6 @@ std::string AssStyle::GetSSAText() const {
% Margin[0] % Margin[1] % Margin[2] % encoding);
}
-AssEntry *AssStyle::Clone() const {
- return new AssStyle(*this);
-}
-
void AssStyle::GetEncodings(wxArrayString &encodingStrings) {
encodingStrings.Clear();
encodingStrings.Add(wxString("0 - ") + _("ANSI"));
diff --git a/aegisub/src/ass_style.h b/aegisub/src/ass_style.h
index 149fd3d13..aaf2b15a5 100644
--- a/aegisub/src/ass_style.h
+++ b/aegisub/src/ass_style.h
@@ -80,7 +80,7 @@ public:
const std::string GetEntryData() const override { return data; }
std::string GetSSAText() const override;
AssEntryGroup Group() const override { return AssEntryGroup::STYLE; }
- AssEntry *Clone() const override;
+ AssStyle *Clone() const override { return new AssStyle(*this); }
/// Convert an ASS alignment to the equivalent SSA alignment
static int AssToSsa(int ass_align);
diff --git a/aegisub/src/audio_karaoke.cpp b/aegisub/src/audio_karaoke.cpp
index f2e9270b3..500d9bb46 100644
--- a/aegisub/src/audio_karaoke.cpp
+++ b/aegisub/src/audio_karaoke.cpp
@@ -117,7 +117,7 @@ void AudioKaraoke::OnActiveLineChanged(AssDialogue *new_line) {
}
}
-void AudioKaraoke::OnFileChanged(int type, std::set const& changed) {
+void AudioKaraoke::OnFileChanged(int type, std::set const& changed) {
if (enabled && (type & AssFile::COMMIT_DIAG_FULL) && (changed.empty() || changed.count(active_line))) {
LoadFromLine();
split_area->Refresh(false);
diff --git a/aegisub/src/audio_karaoke.h b/aegisub/src/audio_karaoke.h
index cf4a293a6..e026cb282 100644
--- a/aegisub/src/audio_karaoke.h
+++ b/aegisub/src/audio_karaoke.h
@@ -31,7 +31,6 @@
#include
class AssDialogue;
-class AssEntry;
class AssKaraoke;
class wxButton;
@@ -144,7 +143,7 @@ class AudioKaraoke : public wxWindow {
void OnActiveLineChanged(AssDialogue *new_line);
void OnContextMenu(wxContextMenuEvent&);
void OnEnableButton(wxCommandEvent &evt);
- void OnFileChanged(int type, std::set const& changed);
+ void OnFileChanged(int type, std::set const& changed);
void OnMouse(wxMouseEvent &event);
void OnPaint(wxPaintEvent &event);
void OnSize(wxSizeEvent &event);
diff --git a/aegisub/src/audio_timing_dialogue.cpp b/aegisub/src/audio_timing_dialogue.cpp
index f29ea64d1..748d1ac3b 100644
--- a/aegisub/src/audio_timing_dialogue.cpp
+++ b/aegisub/src/audio_timing_dialogue.cpp
@@ -715,21 +715,19 @@ void AudioTimingControllerDialogue::SetMarkers(std::vector const&
AnnounceMarkerMoved();
}
-static bool noncomment_dialogue(AssEntry const& e)
+static bool noncomment_dialogue(AssDialogue const& diag)
{
- if (const AssDialogue *diag = dynamic_cast(&e))
- return !diag->Comment;
- return false;
+ return !diag.Comment;
}
-static bool dialogue(AssEntry const& e)
+static bool dialogue(AssDialogue const&)
{
- return !!dynamic_cast(&e);
+ return true;
}
void AudioTimingControllerDialogue::RegenerateInactiveLines()
{
- bool (*predicate)(AssEntry const&) = inactive_line_comments->GetBool() ? dialogue : noncomment_dialogue;
+ auto predicate = inactive_line_comments->GetBool() ? dialogue : noncomment_dialogue;
bool was_empty = inactive_lines.empty();
inactive_lines.clear();
@@ -742,21 +740,20 @@ void AudioTimingControllerDialogue::RegenerateInactiveLines()
case 2: // Previous and next lines
if (AssDialogue *line = context->selectionController->GetActiveLine())
{
- entryIter current_line = context->ass->Events.iterator_to(*line);
+ auto current_line = context->ass->Events.iterator_to(*line);
if (current_line == context->ass->Events.end())
break;
- entryIter prev = current_line;
+ auto prev = current_line;
while (--prev != context->ass->Events.begin() && !predicate(*prev)) ;
if (prev != context->ass->Events.begin())
- AddInactiveLine(sel, static_cast(&*prev));
+ AddInactiveLine(sel, &*prev);
if (mode == 2)
{
- entryIter next =
- find_if(++current_line, context->ass->Events.end(), predicate);
+ auto next = find_if(++current_line, context->ass->Events.end(), predicate);
if (next != context->ass->Events.end())
- AddInactiveLine(sel, static_cast(&*next));
+ AddInactiveLine(sel, &*next);
}
}
break;
@@ -766,7 +763,7 @@ void AudioTimingControllerDialogue::RegenerateInactiveLines()
for (auto& line : context->ass->Events)
{
if (&line != active_line && predicate(line))
- AddInactiveLine(sel, static_cast(&line));
+ AddInactiveLine(sel, &line);
}
break;
}
diff --git a/aegisub/src/auto4_lua.cpp b/aegisub/src/auto4_lua.cpp
index 6ba8f4123..51b3a6c0a 100644
--- a/aegisub/src/auto4_lua.cpp
+++ b/aegisub/src/auto4_lua.cpp
@@ -277,7 +277,7 @@ namespace {
lua_pushvalue(L, 1);
std::unique_ptr et(Automation4::LuaAssFile::LuaToAssEntry(L));
- AssStyle *st = dynamic_cast(et.get());
+ auto st = dynamic_cast(et.get());
lua_pop(L, 1);
if (!st)
return luaL_error(L, "Not a style entry");
@@ -843,9 +843,8 @@ namespace Automation4 {
int idx = 1;
for (auto& line : c->ass->Events) {
++row;
- auto diag = static_cast(&line);
- if (diag == active_line) active_idx = row;
- if (sel.count(diag)) {
+ if (&line == active_line) active_idx = row;
+ if (sel.count(&line)) {
push_value(L, row);
lua_rawseti(L, -2, idx++);
}
@@ -928,7 +927,7 @@ namespace Automation4 {
throw LuaForEachBreak();
}
- AssDialogue *diag = dynamic_cast(lines[cur - 1]);
+ auto diag = dynamic_cast(lines[cur - 1]);
if (!diag) {
wxLogError("Selected row %d is not a dialogue line", cur);
throw LuaForEachBreak();
diff --git a/aegisub/src/auto4_lua_assfile.cpp b/aegisub/src/auto4_lua_assfile.cpp
index 87350f3e3..ecb77e661 100644
--- a/aegisub/src/auto4_lua_assfile.cpp
+++ b/aegisub/src/auto4_lua_assfile.cpp
@@ -37,6 +37,7 @@
#include "auto4_lua.h"
#include "auto4_lua_utils.h"
+#include "ass_attachment.h"
#include "ass_dialogue.h"
#include "ass_info.h"
#include "ass_file.h"
@@ -535,7 +536,7 @@ namespace Automation4 {
int LuaAssFile::LuaParseKaraokeData(lua_State *L)
{
auto e = LuaToAssEntry(L);
- AssDialogue *dia = dynamic_cast(e.get());
+ auto dia = dynamic_cast(e.get());
luaL_argcheck(L, dia, 1, "Subtitle line must be a dialogue line");
int idx = 0;
diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp
index 0e00ff47a..9ac3f3edf 100644
--- a/aegisub/src/base_grid.cpp
+++ b/aegisub/src/base_grid.cpp
@@ -52,8 +52,6 @@
#include "video_context.h"
#include "video_slider.h"
-#include
-
#include
#include
#include
@@ -82,13 +80,6 @@ enum RowColor {
COLOR_LEFT_COL
};
-template
-static inline void set_difference(const S1 &src1, const S2 &src2, D &dst) {
- std::set_difference(
- src1.begin(), src1.end(), src2.begin(), src2.end(),
- std::inserter(dst, dst.begin()));
-}
-
namespace std {
template
struct hash> {
@@ -265,9 +256,9 @@ void BaseGrid::UpdateMaps() {
index_line_map.clear();
line_index_map.clear();
- for (auto curdiag : context->ass->Events | agi::of_type()) {
- line_index_map[curdiag] = (int)index_line_map.size();
- index_line_map.push_back(curdiag);
+ for (auto& curdiag : context->ass->Events) {
+ line_index_map[&curdiag] = (int)index_line_map.size();
+ index_line_map.push_back(&curdiag);
}
auto sorted = index_line_map;
@@ -751,6 +742,7 @@ void BaseGrid::SetColumnWidths() {
std::unordered_map, int> widths;
auto get_width = [&](boost::flyweight const& str) -> int {
+ if (str.get().empty()) return 0;
auto it = widths.find(str);
if (it != end(widths)) return it->second;
int width = dc.GetTextExtent(to_wx(str)).GetWidth();
@@ -766,24 +758,22 @@ void BaseGrid::SetColumnWidths() {
int maxLayer = 0;
int maxStart = 0;
int maxEnd = 0;
- for (int i = 0; i < GetRows(); i++) {
- AssDialogue *curDiag = GetDialogue(i);
-
- maxLayer = std::max(maxLayer, curDiag->Layer);
- actorLen = std::max(actorLen, get_width(curDiag->Actor));
- styleLen = std::max(styleLen, get_width(curDiag->Style));
- effectLen = std::max(effectLen, get_width(curDiag->Effect));
+ for (auto const& diag : context->ass->Events) {
+ maxLayer = std::max(maxLayer, diag.Layer);
+ actorLen = std::max(actorLen, get_width(diag.Actor));
+ styleLen = std::max(styleLen, get_width(diag.Style));
+ effectLen = std::max(effectLen, get_width(diag.Effect));
// Margins
for (int j = 0; j < 3; j++) {
- if (curDiag->Margin[j])
+ if (diag.Margin[j])
showMargin[j] = true;
}
// Times
if (byFrame) {
- maxStart = std::max(maxStart, context->videoController->FrameAtTime(curDiag->Start, agi::vfr::START));
- maxEnd = std::max(maxEnd, context->videoController->FrameAtTime(curDiag->End, agi::vfr::END));
+ maxStart = std::max(maxStart, context->videoController->FrameAtTime(diag.Start, agi::vfr::START));
+ maxEnd = std::max(maxEnd, context->videoController->FrameAtTime(diag.End, agi::vfr::END));
}
}
@@ -991,15 +981,19 @@ void BaseGrid::SetSelectionAndActive(Selection const& new_selection, AssDialogue
}
void BaseGrid::PrevLine() {
- int cur_line_i = GetDialogueIndex(GetActiveLine());
- if (AssDialogue *prev_line = GetDialogue(cur_line_i-1))
- SetSelectionAndActive({ prev_line }, prev_line);
+ if (!active_line) return;
+ auto it = context->ass->Events.iterator_to(*active_line);
+ if (it != context->ass->Events.begin()) {
+ --it;
+ SetSelectionAndActive({&*it}, &*it);
+ }
}
void BaseGrid::NextLine() {
- int cur_line_i = GetDialogueIndex(GetActiveLine());
- if (AssDialogue *next_line = GetDialogue(cur_line_i+1))
- SetSelectionAndActive({ next_line }, next_line);
+ if (!active_line) return;
+ auto it = context->ass->Events.iterator_to(*active_line);
+ if (++it != context->ass->Events.end())
+ SetSelectionAndActive({&*it}, &*it);
}
void BaseGrid::AnnounceActiveLineChanged(AssDialogue *new_line) {
diff --git a/aegisub/src/command/edit.cpp b/aegisub/src/command/edit.cpp
index a85e4e96c..ffb6663f5 100644
--- a/aegisub/src/command/edit.cpp
+++ b/aegisub/src/command/edit.cpp
@@ -53,6 +53,7 @@
#include "../utils.h"
#include "../video_context.h"
+#include
#include
#include
@@ -485,12 +486,11 @@ struct edit_find_replace : public Command {
}
};
-static std::string get_entry_data(AssDialogue *d) { return d->GetEntryData(); }
+static std::string get_entry_data(AssDialogue &d) { return d.GetEntryData(); }
static void copy_lines(agi::Context *c) {
SubtitleSelection sel = c->selectionController->GetSelectedSet();
SetClipboard(join(c->ass->Events
- | agi::of_type()
- | filtered([&](AssDialogue *d) { return sel.count(d); })
+ | filtered([&](AssDialogue &d) { return sel.count(&d); })
| transformed(get_entry_data),
"\r\n"));
}
@@ -503,25 +503,25 @@ static void delete_lines(agi::Context *c, wxString const& commit_message) {
AssDialogue *post_sel = nullptr;
bool hit_selection = false;
- for (auto diag : c->ass->Events | agi::of_type()) {
- if (sel.count(diag))
+ for (auto& diag : c->ass->Events) {
+ if (sel.count(&diag))
hit_selection = true;
else if (hit_selection && !post_sel) {
- post_sel = diag;
+ post_sel = &diag;
break;
}
else
- pre_sel = diag;
+ pre_sel = &diag;
}
// Remove the selected lines, but defer the deletion until after we select
// different lines. We can't just change the selection first because we may
// need to create a new dialogue line for it, and we can't select dialogue
// lines until after they're committed.
- std::vector> to_delete;
- c->ass->Events.remove_and_dispose_if([&sel](AssEntry const& e) {
- return sel.count(const_cast(static_cast(&e)));
- }, [&](AssEntry *e) {
+ std::vector> to_delete;
+ c->ass->Events.remove_and_dispose_if([&sel](AssDialogue const& e) {
+ return sel.count(const_cast(&e));
+ }, [&](AssDialogue *e) {
to_delete.emplace_back(e);
});
@@ -591,35 +591,28 @@ struct edit_line_delete : public validate_sel_nonempty {
}
};
-struct in_selection : public std::unary_function {
- SubtitleSelectionController::Selection const& sel;
- in_selection(SubtitleSelectionController::Selection const& sel) : sel(sel) { }
- bool operator()(AssEntry const& e) const {
- const AssDialogue *d = dynamic_cast(&e);
- return d && sel.count(const_cast(d));
- }
-};
-
static void duplicate_lines(agi::Context *c, int shift) {
- in_selection sel(c->selectionController->GetSelectedSet());
+ auto const& sel = c->selectionController->GetSelectedSet();
+ auto in_selection = [&](AssDialogue const& d) { return sel.count(const_cast(&d)); };
+
SubtitleSelectionController::Selection new_sel;
AssDialogue *new_active = nullptr;
- entryIter start = c->ass->Events.begin();
- entryIter end = c->ass->Events.end();
+ auto start = c->ass->Events.begin();
+ auto end = c->ass->Events.end();
while (start != end) {
// Find the first line in the selection
- start = find_if(start, end, sel);
+ start = find_if(start, end, in_selection);
if (start == end) break;
// And the last line in this contiguous selection
- entryIter insert_pos = find_if_not(start, end, sel);
- entryIter last = std::prev(insert_pos);
+ auto insert_pos = find_if_not(start, end, in_selection);
+ auto last = std::prev(insert_pos);
// Duplicate each of the selected lines, inserting them in a block
// after the selected block
do {
- auto old_diag = static_cast(&*start);
+ auto old_diag = &*start;
auto new_diag = new AssDialogue(*old_diag);
c->ass->Events.insert(insert_pos, *new_diag);
@@ -703,10 +696,9 @@ static void combine_lines(agi::Context *c, void (*combiner)(AssDialogue *, AssDi
SubtitleSelection sel = c->selectionController->GetSelectedSet();
AssDialogue *first = nullptr;
- for (entryIter it = c->ass->Events.begin(); it != c->ass->Events.end(); ) {
- AssDialogue *diag = dynamic_cast(&*it++);
- if (!diag || !sel.count(diag))
- continue;
+ for (auto it = c->ass->Events.begin(); it != c->ass->Events.end(); ) {
+ AssDialogue *diag = &*it++;
+ if (!sel.count(diag)) continue;
if (!first) {
first = diag;
continue;
@@ -772,7 +764,7 @@ static bool try_paste_lines(agi::Context *c) {
boost::trim_left(data);
if (!boost::starts_with(data, "Dialogue:")) return false;
- EntryList parsed;
+ EntryList parsed;
boost::char_separator sep("\r\n");
for (auto curdata : boost::tokenizer>(data, sep)) {
boost::trim(curdata);
@@ -780,15 +772,15 @@ static bool try_paste_lines(agi::Context *c) {
parsed.push_back(*new AssDialogue(curdata));
}
catch (...) {
- parsed.clear_and_dispose([](AssEntry *e) { delete e; });
+ parsed.clear_and_dispose([](AssDialogue *e) { delete e; });
return false;
}
}
- AssDialogue *new_active = static_cast(&*parsed.begin());
+ AssDialogue *new_active = &*parsed.begin();
SubtitleSelection new_selection;
for (auto& line : parsed)
- new_selection.insert(static_cast(&line));
+ new_selection.insert(&line);
auto pos = c->ass->Events.iterator_to(*c->selectionController->GetActiveLine());
c->ass->Events.splice(pos, parsed, parsed.begin(), parsed.end());
@@ -858,9 +850,9 @@ struct edit_line_paste_over : public Command {
std::unique_ptr deleter(new_line);
if (pos == c->ass->Events.end()) return nullptr;
- AssDialogue *ret = paste_over(c->parent, pasteOverOptions, new_line, static_cast(&*pos));
+ AssDialogue *ret = paste_over(c->parent, pasteOverOptions, new_line, &*pos);
if (ret)
- pos = find_if(next(pos), c->ass->Events.end(), cast());
+ ++pos;
return ret;
});
}
@@ -871,8 +863,8 @@ struct edit_line_paste_over : public Command {
std::vector sorted_selection;
sorted_selection.reserve(sel.size());
for (auto& line : c->ass->Events) {
- if (sel.count(static_cast(&line)))
- sorted_selection.push_back(static_cast(&line));
+ if (sel.count(&line))
+ sorted_selection.push_back(&line);
}
auto pos = begin(sorted_selection);
@@ -936,7 +928,10 @@ struct edit_line_recombine : public validate_sel_multiple {
auto active_line = c->selectionController->GetActiveLine();
std::vector sel(sel_set.begin(), sel_set.end());
- boost::sort(sel, &AssFile::CompStart);
+ boost::sort(sel, [](const AssDialogue *a, const AssDialogue *b) {
+ return a->Start < b->Start;
+ });
+
for (auto &diag : sel)
diag->Text = trim_text(diag->Text);
@@ -983,7 +978,7 @@ struct edit_line_recombine : public validate_sel_multiple {
// Remove now non-existent lines from the selection
SubtitleSelection lines, new_sel;
- boost::copy(c->ass->Events | agi::of_type(), inserter(lines, lines.begin()));
+ boost::copy(c->ass->Events | agi::address_of, inserter(lines, lines.begin()));
boost::set_intersection(lines, sel_set, inserter(new_sel, new_sel.begin()));
if (new_sel.empty())
diff --git a/aegisub/src/command/grid.cpp b/aegisub/src/command/grid.cpp
index b51043c63..e63a70d22 100644
--- a/aegisub/src/command/grid.cpp
+++ b/aegisub/src/command/grid.cpp
@@ -79,7 +79,7 @@ struct grid_line_next_create : public Command {
newline->End = cur->End + OPT_GET("Timing/Default Duration")->GetInt();
newline->Style = cur->Style;
- entryIter pos = c->ass->Events.iterator_to(*cur);
+ auto pos = c->ass->Events.iterator_to(*cur);
c->ass->Events.insert(++pos, *newline);
c->ass->Commit(_("line insertion"), AssFile::COMMIT_DIAG_ADDREM);
c->selectionController->NextLine();
@@ -328,9 +328,7 @@ static bool move_one(T begin, T end, U const& to_move, int step) {
size_t move_count = 0;
auto prev = end;
for (auto it = begin; it != end; std::advance(it, step)) {
- auto cur = dynamic_cast(&*it);
- if (!cur) continue;
-
+ auto cur = &*it;
if (!to_move.count(cur))
prev = it;
else if (prev != end) {
diff --git a/aegisub/src/command/subtitle.cpp b/aegisub/src/command/subtitle.cpp
index 89ee24ef6..80bfe9544 100644
--- a/aegisub/src/command/subtitle.cpp
+++ b/aegisub/src/command/subtitle.cpp
@@ -53,10 +53,11 @@
#include "../utils.h"
#include "../video_context.h"
+#include
#include
-#include
#include
+#include
#include
#include
@@ -124,7 +125,7 @@ static void insert_subtitle_at_video(agi::Context *c, bool after) {
def->End = video_ms + OPT_GET("Timing/Default Duration")->GetInt();
def->Style = c->selectionController->GetActiveLine()->Style;
- entryIter pos = c->ass->Events.iterator_to(*c->selectionController->GetActiveLine());
+ auto pos = c->ass->Events.iterator_to(*c->selectionController->GetActiveLine());
if (after) ++pos;
c->ass->Events.insert(pos, *def);
@@ -147,8 +148,8 @@ struct subtitle_insert_after : public validate_nonempty_selection {
new_line->Start = active_line->End;
new_line->End = new_line->Start + OPT_GET("Timing/Default Duration")->GetInt();
- for (entryIter it = c->ass->Events.begin(); it != c->ass->Events.end(); ++it) {
- AssDialogue *diag = static_cast(&*it);
+ for (auto it = c->ass->Events.begin(); it != c->ass->Events.end(); ++it) {
+ AssDialogue *diag = &*it;
// Limit the line to the available time
if (diag->Start >= new_line->Start)
@@ -192,8 +193,8 @@ struct subtitle_insert_before : public validate_nonempty_selection {
new_line->End = active_line->Start;
new_line->Start = new_line->End - OPT_GET("Timing/Default Duration")->GetInt();
- for (entryIter it = c->ass->Events.begin(); it != c->ass->Events.end(); ++it) {
- auto diag = static_cast(&*it);
+ for (auto it = c->ass->Events.begin(); it != c->ass->Events.end(); ++it) {
+ auto diag = &*it;
// Limit the line to the available time
if (diag->End <= new_line->End)
@@ -372,9 +373,7 @@ struct subtitle_select_all : public Command {
void operator()(agi::Context *c) override {
SubtitleSelection sel;
- transform(c->ass->Events.begin(), c->ass->Events.end(),
- inserter(sel, sel.begin()), cast());
- sel.erase(nullptr);
+ boost::copy(c->ass->Events | agi::address_of, inserter(sel, sel.end()));
c->selectionController->SetSelectedSet(sel);
}
};
@@ -394,13 +393,13 @@ struct subtitle_select_visible : public Command {
SubtitleSelectionController::Selection new_selection;
int frame = c->videoController->GetFrameN();
- for (auto diag : c->ass->Events | agi::of_type()) {
- if (c->videoController->FrameAtTime(diag->Start, agi::vfr::START) <= frame &&
- c->videoController->FrameAtTime(diag->End, agi::vfr::END) >= frame)
+ for (auto& diag : c->ass->Events) {
+ if (c->videoController->FrameAtTime(diag.Start, agi::vfr::START) <= frame &&
+ c->videoController->FrameAtTime(diag.End, agi::vfr::END) >= frame)
{
if (new_selection.empty())
- c->selectionController->SetActiveLine(diag);
- new_selection.insert(diag);
+ c->selectionController->SetActiveLine(&diag);
+ new_selection.insert(&diag);
}
}
diff --git a/aegisub/src/command/time.cpp b/aegisub/src/command/time.cpp
index 5bceb7155..eeb73017e 100644
--- a/aegisub/src/command/time.cpp
+++ b/aegisub/src/command/time.cpp
@@ -45,7 +45,6 @@
#include "../selection_controller.h"
#include "../video_context.h"
-#include
#include
#include
@@ -67,8 +66,8 @@ namespace {
if (sel.size() < 2) return !sel.empty();
size_t found = 0;
- for (auto diag : c->ass->Events | agi::of_type()) {
- if (sel.count(diag)) {
+ for (auto& diag : c->ass->Events) {
+ if (sel.count(&diag)) {
if (++found == sel.size())
return true;
}
@@ -84,14 +83,14 @@ static void adjoin_lines(agi::Context *c, bool set_start) {
AssDialogue *prev = nullptr;
size_t seen = 0;
bool prev_sel = false;
- for (auto diag : c->ass->Events | agi::of_type()) {
- bool cur_sel = !!sel.count(diag);
+ for (auto diag : c->ass->Events) {
+ bool cur_sel = !!sel.count(&diag);
if (prev) {
// One row selections act as if the previous or next line was selected
if (set_start && cur_sel && (sel.size() == 1 || prev_sel))
- diag->Start = prev->End;
+ diag.Start = prev->End;
else if (!set_start && prev_sel && (cur_sel || sel.size() == 1))
- prev->End = diag->Start;
+ prev->End = diag.Start;
}
if (seen == sel.size())
@@ -100,7 +99,7 @@ static void adjoin_lines(agi::Context *c, bool set_start) {
if (cur_sel)
++seen;
- prev = diag;
+ prev = &diag;
prev_sel = cur_sel;
}
diff --git a/aegisub/src/dialog_attachments.cpp b/aegisub/src/dialog_attachments.cpp
index dc4de6e18..50434ed72 100644
--- a/aegisub/src/dialog_attachments.cpp
+++ b/aegisub/src/dialog_attachments.cpp
@@ -50,8 +50,6 @@
#include "options.h"
#include "utils.h"
-#include
-
DialogAttachments::DialogAttachments(wxWindow *parent, AssFile *ass)
: wxDialog(parent, -1, _("Attachment List"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
, ass(ass)
@@ -99,12 +97,12 @@ void DialogAttachments::UpdateList() {
listView->InsertColumn(1, _("Size"), wxLIST_FORMAT_LEFT, 100);
listView->InsertColumn(2, _("Group"), wxLIST_FORMAT_LEFT, 100);
- for (auto attach : ass->Attachments | agi::of_type()) {
+ for (auto& attach : ass->Attachments) {
int row = listView->GetItemCount();
- listView->InsertItem(row, to_wx(attach->GetFileName(true)));
- listView->SetItem(row, 1, PrettySize(attach->GetSize()));
- listView->SetItem(row, 2, to_wx(attach->GroupHeader()));
- listView->SetItemPtrData(row, wxPtrToUInt(attach));
+ listView->InsertItem(row, to_wx(attach.GetFileName(true)));
+ listView->SetItem(row, 1, PrettySize(attach.GetSize()));
+ listView->SetItem(row, 2, to_wx(attach.GroupHeader()));
+ listView->SetItemPtrData(row, wxPtrToUInt(&attach));
}
}
diff --git a/aegisub/src/dialog_kara_timing_copy.cpp b/aegisub/src/dialog_kara_timing_copy.cpp
index 135cca6ee..030bff8e3 100644
--- a/aegisub/src/dialog_kara_timing_copy.cpp
+++ b/aegisub/src/dialog_kara_timing_copy.cpp
@@ -601,8 +601,8 @@ void DialogKanjiTimer::OnAccept(wxCommandEvent &) {
if (display->GetRemainingSource() > 0)
wxMessageBox(_("Group all of the source text."),_("Error"),wxICON_EXCLAMATION | wxOK);
- else if (AssDialogue *destLine = dynamic_cast(currentDestinationLine)) {
- LinesToChange.push_back(std::make_pair(destLine, display->GetOutputLine()));
+ else {
+ LinesToChange.push_back(std::make_pair(currentDestinationLine, display->GetOutputLine()));
currentSourceLine = FindNextStyleMatch(currentSourceLine, from_wx(SourceStyle->GetValue()));
currentDestinationLine = FindNextStyleMatch(currentDestinationLine, from_wx(DestStyle->GetValue()));
@@ -644,21 +644,13 @@ void DialogKanjiTimer::OnKeyDown(wxKeyEvent &event) {
void DialogKanjiTimer::ResetForNewLine()
{
- AssDialogue *src = nullptr;
- AssDialogue *dst = nullptr;
-
- if (currentSourceLine)
- src = dynamic_cast(currentSourceLine);
- if (currentDestinationLine)
- dst = dynamic_cast(currentDestinationLine);
-
- if (!src || !dst)
+ if (!currentSourceLine || !currentDestinationLine)
{
- src = dst = nullptr;
+ currentSourceLine = currentDestinationLine = nullptr;
wxBell();
}
- display->SetInputData(src, dst);
+ display->SetInputData(currentSourceLine, currentDestinationLine);
TryAutoMatch();
@@ -672,25 +664,24 @@ void DialogKanjiTimer::TryAutoMatch()
}
template
-static AssEntry *find_next(Iterator from, Iterator to, std::string const& style_name) {
+static AssDialogue *find_next(Iterator from, Iterator to, std::string const& style_name) {
for (; from != to; ++from)
{
- AssDialogue *dlg = dynamic_cast(&*from);
- if (dlg && dlg->Style == style_name && !dlg->Text.get().empty())
- return dlg;
+ if (from->Style == style_name && !from->Text.get().empty())
+ return &*from;
}
return nullptr;
}
-AssEntry *DialogKanjiTimer::FindNextStyleMatch(AssEntry *search_from, const std::string &search_style)
+AssDialogue *DialogKanjiTimer::FindNextStyleMatch(AssDialogue *search_from, const std::string &search_style)
{
if (!search_from) return search_from;
return find_next(++subs->Events.iterator_to(*search_from), subs->Events.end(), search_style);
}
-AssEntry *DialogKanjiTimer::FindPrevStyleMatch(AssEntry *search_from, const std::string &search_style)
+AssDialogue *DialogKanjiTimer::FindPrevStyleMatch(AssDialogue *search_from, const std::string &search_style)
{
if (!search_from) return search_from;
- return find_next(EntryList::reverse_iterator(subs->Events.iterator_to(*search_from)), subs->Events.rend(), search_style);
+ return find_next(EntryList::reverse_iterator(subs->Events.iterator_to(*search_from)), subs->Events.rend(), search_style);
}
diff --git a/aegisub/src/dialog_kara_timing_copy.h b/aegisub/src/dialog_kara_timing_copy.h
index c74f0ba1a..ab61b3ba8 100644
--- a/aegisub/src/dialog_kara_timing_copy.h
+++ b/aegisub/src/dialog_kara_timing_copy.h
@@ -39,7 +39,6 @@
namespace agi { struct Context; }
class AssDialogue;
-class AssEntry;
class AssFile;
class KaraokeLineMatchDisplay;
class wxComboBox;
@@ -55,8 +54,8 @@ class DialogKanjiTimer : public wxDialog {
std::vector> LinesToChange;
- AssEntry *currentSourceLine = nullptr;
- AssEntry *currentDestinationLine = nullptr;
+ AssDialogue *currentSourceLine = nullptr;
+ AssDialogue *currentDestinationLine = nullptr;
void OnClose(wxCommandEvent &event);
void OnStart(wxCommandEvent &event);
@@ -71,8 +70,8 @@ class DialogKanjiTimer : public wxDialog {
void ResetForNewLine();
void TryAutoMatch();
- AssEntry *FindNextStyleMatch(AssEntry *search_from, const std::string &search_style);
- AssEntry *FindPrevStyleMatch(AssEntry *search_from, const std::string &search_style);
+ AssDialogue *FindNextStyleMatch(AssDialogue *search_from, const std::string &search_style);
+ AssDialogue *FindPrevStyleMatch(AssDialogue *search_from, const std::string &search_style);
public:
DialogKanjiTimer(agi::Context *context);
diff --git a/aegisub/src/dialog_selection.cpp b/aegisub/src/dialog_selection.cpp
index fdc29027e..d09384c06 100644
--- a/aegisub/src/dialog_selection.cpp
+++ b/aegisub/src/dialog_selection.cpp
@@ -34,8 +34,6 @@
#include "selection_controller.h"
#include "utils.h"
-#include
-
#include
#include
#include
@@ -77,12 +75,12 @@ static std::set process(std::string const& match_text, bool match_
auto predicate = SearchReplaceEngine::GetMatcher(settings);
std::set matches;
- for (auto diag : ass->Events | agi::of_type()) {
- if (diag->Comment && !comments) continue;
- if (!diag->Comment && !dialogue) continue;
+ for (auto& diag : ass->Events) {
+ if (diag.Comment && !comments) continue;
+ if (!diag.Comment && !dialogue) continue;
- if (invert != predicate(diag, 0))
- matches.insert(diag);
+ if (invert != predicate(&diag, 0))
+ matches.insert(&diag);
}
return matches;
diff --git a/aegisub/src/dialog_shift_times.cpp b/aegisub/src/dialog_shift_times.cpp
index 42f3cea2b..772ee15ec 100644
--- a/aegisub/src/dialog_shift_times.cpp
+++ b/aegisub/src/dialog_shift_times.cpp
@@ -38,7 +38,6 @@
#include
#include
#include
-#include
#include
#include
@@ -354,10 +353,10 @@ void DialogShiftTimes::Process(wxCommandEvent &) {
int block_start = 0;
json::Array shifted_blocks;
- for (auto line : context->ass->Events | agi::of_type()) {
+ for (auto& line : context->ass->Events) {
++row_number;
- if (!sel.count(line)) {
+ if (!sel.count(&line)) {
if (block_start) {
json::Object block;
block["start"] = block_start;
@@ -372,9 +371,9 @@ void DialogShiftTimes::Process(wxCommandEvent &) {
block_start = row_number;
if (start)
- line->Start = Shift(line->Start, shift, by_time, agi::vfr::START);
+ line.Start = Shift(line.Start, shift, by_time, agi::vfr::START);
if (end)
- line->End = Shift(line->End, shift, by_time, agi::vfr::END);
+ line.End = Shift(line.End, shift, by_time, agi::vfr::END);
}
context->ass->Commit(_("shifting"), AssFile::COMMIT_DIAG_TIME);
diff --git a/aegisub/src/dialog_spellchecker.cpp b/aegisub/src/dialog_spellchecker.cpp
index 541e5d2f9..10d4ee464 100644
--- a/aegisub/src/dialog_spellchecker.cpp
+++ b/aegisub/src/dialog_spellchecker.cpp
@@ -212,19 +212,17 @@ bool DialogSpellChecker::FindNext() {
if (CheckLine(active_line, start_pos, &commit_id))
return true;
- entryIter it = context->ass->Events.iterator_to(*active_line);
+ auto it = context->ass->Events.iterator_to(*active_line);
// Note that it is deliberate that the start line is checked twice, as if
// the cursor is past the first misspelled word in the current line, that
// word should be hit last
while(!has_looped || active_line != start_line) {
- do {
- // Wrap around to the beginning if we hit the end
- if (++it == context->ass->Events.end()) {
- it = context->ass->Events.begin();
- has_looped = true;
- }
- } while (!(active_line = dynamic_cast(&*it)));
+ // Wrap around to the beginning if we hit the end
+ if (++it == context->ass->Events.end()) {
+ it = context->ass->Events.begin();
+ has_looped = true;
+ }
if (CheckLine(active_line, 0, &commit_id))
return true;
diff --git a/aegisub/src/dialog_style_editor.cpp b/aegisub/src/dialog_style_editor.cpp
index bc5bdfefd..bf730b373 100644
--- a/aegisub/src/dialog_style_editor.cpp
+++ b/aegisub/src/dialog_style_editor.cpp
@@ -86,19 +86,19 @@ class StyleRenamer {
found_any = false;
do_replace = replace;
- for (auto diag : c->ass->Events | agi::of_type()) {
- if (diag->Style == source_name) {
+ for (auto& diag : c->ass->Events) {
+ if (diag.Style == source_name) {
if (replace)
- diag->Style = new_name;
+ diag.Style = new_name;
else
found_any = true;
}
- boost::ptr_vector blocks(diag->ParseTags());
+ boost::ptr_vector blocks(diag.ParseTags());
for (auto block : blocks | agi::of_type())
block->ProcessParameters(&StyleRenamer::ProcessTag, this);
if (replace)
- diag->UpdateText(blocks);
+ diag.UpdateText(blocks);
if (found_any) return;
}
diff --git a/aegisub/src/dialog_style_manager.cpp b/aegisub/src/dialog_style_manager.cpp
index 8737a6a1b..1783a72f2 100644
--- a/aegisub/src/dialog_style_manager.cpp
+++ b/aegisub/src/dialog_style_manager.cpp
@@ -54,7 +54,6 @@
#include
#include
-#include
#include
#include
@@ -288,9 +287,9 @@ void DialogStyleManager::LoadCurrentStyles(int commit_type) {
CurrentList->Clear();
styleMap.clear();
- for (auto style : c->ass->Styles | agi::of_type()) {
- CurrentList->Append(to_wx(style->name));
- styleMap.push_back(style);
+ for (auto& style : c->ass->Styles) {
+ CurrentList->Append(to_wx(style.name));
+ styleMap.push_back(&style);
}
}
@@ -780,10 +779,8 @@ void DialogStyleManager::MoveStyles(bool storage, int type) {
// Replace styles
size_t curn = 0;
for (auto it = c->ass->Styles.begin(); it != c->ass->Styles.end(); ++it) {
- if (!dynamic_cast(&*it)) continue;
-
auto new_style_at_pos = c->ass->Styles.iterator_to(*styleMap[curn]);
- EntryList::node_algorithms::swap_nodes(it.pointed_node(), new_style_at_pos.pointed_node());
+ EntryList::node_algorithms::swap_nodes(it.pointed_node(), new_style_at_pos.pointed_node());
if (++curn == styleMap.size()) break;
it = new_style_at_pos;
}
diff --git a/aegisub/src/dialog_timing_processor.cpp b/aegisub/src/dialog_timing_processor.cpp
index 2c83d9046..be888e136 100644
--- a/aegisub/src/dialog_timing_processor.cpp
+++ b/aegisub/src/dialog_timing_processor.cpp
@@ -48,8 +48,12 @@
#include "utils.h"
#include "video_context.h"
+#include
+
#include
+#include
#include
+#include
#include
#include
@@ -63,6 +67,8 @@
#include
#include
+using namespace boost::adaptors;
+
namespace {
using std::placeholders::_1;
@@ -288,10 +294,6 @@ void DialogTimingProcessor::OnApply(wxCommandEvent &) {
EndModal(0);
}
-static bool bad_line(std::set *styles, AssDialogue *d) {
- return !d || d->Comment || styles->find(d->Style) == styles->end();
-}
-
std::vector DialogTimingProcessor::SortDialogues() {
std::set styles;
for (size_t i = 0; i < StyleList->GetCount(); ++i) {
@@ -301,14 +303,13 @@ std::vector DialogTimingProcessor::SortDialogues() {
std::vector sorted;
- if (onlySelection->IsChecked()) {
- SubtitleSelection sel = c->selectionController->GetSelectedSet();
- copy_if(sel.begin(), sel.end(), back_inserter(sorted),
- [&](AssDialogue *d) { return !d->Comment && styles.count(d->Style); });
- }
+ auto valid_line = [&](const AssDialogue *d) { return !d->Comment && styles.count(d->Style); };
+ if (onlySelection->IsChecked())
+ boost::copy(c->selectionController->GetSelectedSet() | filtered(valid_line),
+ back_inserter(sorted));
else {
- transform(c->ass->Events.begin(), c->ass->Events.end(), back_inserter(sorted), cast());
- sorted.erase(boost::remove_if(sorted, bind(bad_line, &styles, _1)), sorted.end());
+ sorted.reserve(c->ass->Events.size());
+ boost::push_back(sorted, c->ass->Events | agi::address_of | filtered(valid_line));
}
// Check if rows are valid
@@ -324,7 +325,9 @@ std::vector DialogTimingProcessor::SortDialogues() {
}
}
- boost::sort(sorted, AssFile::CompStart);
+ boost::sort(sorted, [](const AssDialogue *a, const AssDialogue *b) {
+ return a->Start < b->Start;
+ });
return sorted;
}
diff --git a/aegisub/src/export_fixstyle.cpp b/aegisub/src/export_fixstyle.cpp
index 04a71c672..54de56bdd 100644
--- a/aegisub/src/export_fixstyle.cpp
+++ b/aegisub/src/export_fixstyle.cpp
@@ -40,11 +40,8 @@
#include "ass_dialogue.h"
#include "compat.h"
-#include
-
#include
#include
-#include
#include
AssFixStylesFilter::AssFixStylesFilter()
@@ -53,12 +50,12 @@ AssFixStylesFilter::AssFixStylesFilter()
}
void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *) {
- std::vector styles = subs->GetStyles();
- for_each(begin(styles), end(styles), [](std::string& str) { boost::to_lower(str); });
+ auto styles = subs->GetStyles();
+ for (auto& str : styles) boost::to_lower(str);
sort(begin(styles), end(styles));
- for (auto diag : subs->Events | agi::of_type()) {
- if (!binary_search(begin(styles), end(styles), boost::to_lower_copy(diag->Style.get())))
- diag->Style = "Default";
+ for (auto& diag : subs->Events) {
+ if (!binary_search(begin(styles), end(styles), boost::to_lower_copy(diag.Style.get())))
+ diag.Style = "Default";
}
}
diff --git a/aegisub/src/export_framerate.cpp b/aegisub/src/export_framerate.cpp
index a827479fd..b7d4f1edd 100644
--- a/aegisub/src/export_framerate.cpp
+++ b/aegisub/src/export_framerate.cpp
@@ -201,20 +201,20 @@ void AssTransformFramerateFilter::TransformTimeTags(std::string const& name, Ass
void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
if (!Input->IsLoaded() || !Output->IsLoaded()) return;
- for (auto curDialogue : subs->Events | agi::of_type()) {
- line = curDialogue;
+ for (auto& curDialogue : subs->Events) {
+ line = &curDialogue;
newK = 0;
oldK = 0;
- newStart = trunc_cs(ConvertTime(curDialogue->Start));
- newEnd = trunc_cs(ConvertTime(curDialogue->End) + 9);
+ newStart = trunc_cs(ConvertTime(curDialogue.Start));
+ newEnd = trunc_cs(ConvertTime(curDialogue.End) + 9);
// Process stuff
boost::ptr_vector blocks;
for (auto block : blocks | agi::of_type())
block->ProcessParameters(TransformTimeTags, this);
- curDialogue->Start = newStart;
- curDialogue->End = newEnd;
- curDialogue->UpdateText(blocks);
+ curDialogue.Start = newStart;
+ curDialogue.End = newEnd;
+ curDialogue.UpdateText(blocks);
}
}
diff --git a/aegisub/src/font_file_lister.cpp b/aegisub/src/font_file_lister.cpp
index f6d57d932..5bbfbb1e0 100644
--- a/aegisub/src/font_file_lister.cpp
+++ b/aegisub/src/font_file_lister.cpp
@@ -29,8 +29,6 @@
#include "compat.h"
#include "utils.h"
-#include
-
#include
#include
#include
@@ -182,17 +180,17 @@ std::vector FontCollector::GetFontPaths(const AssFile *file) {
status_callback(_("Parsing file\n"), 0);
- for (auto style : file->Styles | agi::of_type()) {
- StyleInfo &info = styles[style->name];
- info.facename = style->font;
- info.bold = style->bold;
- info.italic = style->italic;
- used_styles[info].styles.insert(style->name);
+ for (auto const& style : file->Styles) {
+ StyleInfo &info = styles[style.name];
+ info.facename = style.font;
+ info.bold = style.bold;
+ info.italic = style.italic;
+ used_styles[info].styles.insert(style.name);
}
int index = 0;
- for (auto diag : file->Events | agi::of_type())
- ProcessDialogueLine(diag, ++index);
+ for (auto const& diag : file->Events)
+ ProcessDialogueLine(&diag, ++index);
status_callback(_("Searching for font files\n"), 0);
for_each(used_styles.begin(), used_styles.end(), bind(&FontCollector::ProcessChunk, this, _1));
diff --git a/aegisub/src/resolution_resampler.cpp b/aegisub/src/resolution_resampler.cpp
index 069e0f7be..c1179fe11 100644
--- a/aegisub/src/resolution_resampler.cpp
+++ b/aegisub/src/resolution_resampler.cpp
@@ -125,32 +125,33 @@ namespace {
cur->Set((cur->Get() + shift) * resizer + 0.5);
}
- void resample_line(resample_state *state, AssEntry &line) {
- AssDialogue *diag = dynamic_cast(&line);
- if (diag && !(diag->Comment && (boost::starts_with(diag->Effect.get(), "template") || boost::starts_with(diag->Effect.get(), "code")))) {
- boost::ptr_vector blocks(diag->ParseTags());
+ void resample_line(resample_state *state, AssDialogue &diag) {
+ if (diag.Comment && (boost::starts_with(diag.Effect.get(), "template") || boost::starts_with(diag.Effect.get(), "code")))
+ return;
- for (auto block : blocks | agi::of_type())
- block->ProcessParameters(resample_tags, state);
+ boost::ptr_vector blocks(diag.ParseTags());
- for (auto drawing : blocks | agi::of_type())
- drawing->text = transform_drawing(drawing->text, state->margin[LEFT], state->margin[TOP], state->rx, state->ry);
+ for (auto block : blocks | agi::of_type())
+ block->ProcessParameters(resample_tags, state);
- for (size_t i = 0; i < 3; ++i)
- diag->Margin[i] = int((diag->Margin[i] + state->margin[i]) * (i < 2 ? state->rx : state->ry) + 0.5);
+ for (auto drawing : blocks | agi::of_type())
+ drawing->text = transform_drawing(drawing->text, state->margin[LEFT], state->margin[TOP], state->rx, state->ry);
- diag->UpdateText(blocks);
- }
- else if (AssStyle *style = dynamic_cast(&line)) {
- style->fontsize = int(style->fontsize * state->ry + 0.5);
- style->outline_w *= state->ry;
- style->shadow_w *= state->ry;
- style->spacing *= state->rx;
- style->scalex *= state->ar;
- for (int i = 0; i < 3; i++)
- style->Margin[i] = int((style->Margin[i] + state->margin[i]) * (i < 2 ? state->rx : state->ry) + 0.5);
- style->UpdateData();
- }
+ for (size_t i = 0; i < 3; ++i)
+ diag.Margin[i] = int((diag.Margin[i] + state->margin[i]) * (i < 2 ? state->rx : state->ry) + 0.5);
+
+ diag.UpdateText(blocks);
+ }
+
+ void resample_style(resample_state *state, AssStyle &style) {
+ style.fontsize = int(style.fontsize * state->ry + 0.5);
+ style.outline_w *= state->ry;
+ style.shadow_w *= state->ry;
+ style.spacing *= state->rx;
+ style.scalex *= state->ar;
+ for (int i = 0; i < 3; i++)
+ style.Margin[i] = int((style.Margin[i] + state->margin[i]) * (i < 2 ? state->rx : state->ry) + 0.5);
+ style.UpdateData();
}
}
@@ -173,7 +174,7 @@ void ResampleResolution(AssFile *ass, ResampleSettings const& settings) {
state.ar = state.rx / state.ry;
for (auto& line : ass->Styles)
- resample_line(&state, line);
+ resample_style(&state, line);
for (auto& line : ass->Events)
resample_line(&state, line);
diff --git a/aegisub/src/search_replace_engine.cpp b/aegisub/src/search_replace_engine.cpp
index b821e08dd..e28598a71 100644
--- a/aegisub/src/search_replace_engine.cpp
+++ b/aegisub/src/search_replace_engine.cpp
@@ -24,7 +24,6 @@
#include "selection_controller.h"
#include "text_selection_controller.h"
-#include
#include
#include
@@ -269,17 +268,15 @@ bool SearchReplaceEngine::FindReplace(bool replace) {
bool selection_only = sel.size() > 1 && settings.limit_to == SearchReplaceSettings::Limit::SELECTED;
do {
- AssDialogue *diag = dynamic_cast(&*it);
- if (!diag) continue;
- if (selection_only && !sel.count(diag)) continue;
- if (settings.ignore_comments && diag->Comment) continue;
+ if (selection_only && !sel.count(&*it)) continue;
+ if (settings.ignore_comments && it->Comment) continue;
- if (MatchState ms = matches(diag, pos)) {
+ if (MatchState ms = matches(&*it, pos)) {
if (selection_only)
// We're cycling through the selection, so don't muck with it
- context->selectionController->SetActiveLine(diag);
+ context->selectionController->SetActiveLine(&*it);
else
- context->selectionController->SetSelectionAndActive({ diag }, diag);
+ context->selectionController->SetSelectionAndActive({ &*it }, &*it);
if (settings.field == SearchReplaceSettings::Field::TEXT)
context->textSelectionController->SetSelection(ms.start, ms.end);
@@ -307,13 +304,13 @@ bool SearchReplaceEngine::ReplaceAll() {
SubtitleSelection const& sel = context->selectionController->GetSelectedSet();
bool selection_only = settings.limit_to == SearchReplaceSettings::Limit::SELECTED;
- for (auto diag : context->ass->Events | agi::of_type()) {
- if (selection_only && !sel.count(diag)) continue;
- if (settings.ignore_comments && diag->Comment) continue;
+ for (auto& diag : context->ass->Events) {
+ if (selection_only && !sel.count(&diag)) continue;
+ if (settings.ignore_comments && diag.Comment) continue;
if (settings.use_regex) {
- if (MatchState ms = matches(diag, 0)) {
- auto& diag_field = diag->*get_dialogue_field(settings.field);
+ if (MatchState ms = matches(&diag, 0)) {
+ auto& diag_field = diag.*get_dialogue_field(settings.field);
std::string const& text = diag_field.get();
count += distance(
boost::u32regex_iterator(begin(text), end(text), *ms.re),
@@ -324,9 +321,9 @@ bool SearchReplaceEngine::ReplaceAll() {
}
size_t pos = 0;
- while (MatchState ms = matches(diag, pos)) {
+ while (MatchState ms = matches(&diag, pos)) {
++count;
- Replace(diag, ms);
+ Replace(&diag, ms);
pos = ms.end;
}
}
diff --git a/aegisub/src/subs_controller.cpp b/aegisub/src/subs_controller.cpp
index d1835f9b6..a82846362 100644
--- a/aegisub/src/subs_controller.cpp
+++ b/aegisub/src/subs_controller.cpp
@@ -70,26 +70,22 @@ struct SubsController::UndoInfo {
: undo_description(d), commit_id(commit_id)
{
script_info.reserve(c->ass->Info.size());
- for (auto const& line : c->ass->Info) {
- auto info = static_cast(&line);
- script_info.emplace_back(info->Key(), info->Value());
- }
+ for (auto const& info : c->ass->Info)
+ script_info.emplace_back(info.Key(), info.Value());
styles.reserve(c->ass->Styles.size());
- for (auto const& line : c->ass->Styles)
- styles.push_back(static_cast(line));
+ styles.assign(c->ass->Styles.begin(), c->ass->Styles.end());
events.reserve(c->ass->Events.size());
- for (auto const& line : c->ass->Events)
- events.push_back(static_cast(line));
+ events.assign(c->ass->Events.begin(), c->ass->Events.end());
for (auto const& line : c->ass->Attachments) {
switch (line.Group()) {
case AssEntryGroup::FONT:
- fonts.push_back(static_cast(line));
+ fonts.push_back(line);
break;
case AssEntryGroup::GRAPHIC:
- graphics.push_back(static_cast(line));
+ graphics.push_back(line);
break;
default:
assert(false);
@@ -364,10 +360,9 @@ void SubsController::OnCommit(AssFileCommit c) {
if (commit_id == *c.commit_id+1 && redo_stack.empty() && saved_commit_id+1 != commit_id && autosaved_commit_id+1 != commit_id) {
// If only one line changed just modify it instead of copying the file
if (c.single_line && c.single_line->Group() == AssEntryGroup::DIALOGUE) {
- auto src_diag = static_cast(c.single_line);
for (auto& diag : undo_stack.back().events) {
- if (diag.Id == src_diag->Id) {
- diag = *src_diag;
+ if (diag.Id == c.single_line->Id) {
+ diag = *c.single_line;
break;
}
}
diff --git a/aegisub/src/subs_controller.h b/aegisub/src/subs_controller.h
index f0c5fbd99..f85571603 100644
--- a/aegisub/src/subs_controller.h
+++ b/aegisub/src/subs_controller.h
@@ -23,7 +23,6 @@
#include
class AssDialogue;
-class AssEntry;
class AssFile;
struct AssFileCommit;
template class SelectionController;
diff --git a/aegisub/src/subs_edit_box.cpp b/aegisub/src/subs_edit_box.cpp
index e365b7a20..012d55a4c 100644
--- a/aegisub/src/subs_edit_box.cpp
+++ b/aegisub/src/subs_edit_box.cpp
@@ -56,7 +56,6 @@
#include "video_context.h"
#include
-#include
#include
#include
@@ -344,7 +343,7 @@ void SubsEditBox::PopulateList(wxComboBox *combo, boost::flyweight
std::unordered_set values;
for (auto const& line : c->ass->Events) {
- auto const& value = static_cast(&line)->*field;
+ auto const& value = line.*field;
if (!value.get().empty())
values.insert(value);
}
diff --git a/aegisub/src/subtitle_format.cpp b/aegisub/src/subtitle_format.cpp
index ec599d648..36355dc69 100644
--- a/aegisub/src/subtitle_format.cpp
+++ b/aegisub/src/subtitle_format.cpp
@@ -57,7 +57,6 @@
#include "video_context.h"
#include
-#include
#include
#include
@@ -94,13 +93,12 @@ bool SubtitleFormat::CanSave(const AssFile *subs) const {
std::string defstyle = AssStyle().GetEntryData();
for (auto const& line : subs->Styles) {
- if (static_cast(&line)->GetEntryData() != defstyle)
+ if (line.GetEntryData() != defstyle)
return false;
}
for (auto const& line : subs->Events) {
- auto diag = static_cast(&line);
- if (diag->GetStrippedText() != diag->Text)
+ if (line.GetStrippedText() != line.Text)
return false;
}
@@ -173,13 +171,13 @@ agi::vfr::Framerate SubtitleFormat::AskForFPS(bool allow_vfr, bool show_smpte) {
}
void SubtitleFormat::StripTags(AssFile &file) {
- for (auto current : file.Events | agi::of_type())
- current->StripTags();
+ for (auto& current : file.Events)
+ current.StripTags();
}
void SubtitleFormat::ConvertNewlines(AssFile &file, std::string const& newline, bool mergeLineBreaks) {
- for (auto current : file.Events | agi::of_type()) {
- std::string repl = current->Text;
+ for (auto& current : file.Events) {
+ std::string repl = current.Text;
boost::replace_all(repl, "\\h", " ");
boost::ireplace_all(repl, "\\n", newline);
if (mergeLineBreaks) {
@@ -188,39 +186,35 @@ void SubtitleFormat::ConvertNewlines(AssFile &file, std::string const& newline,
while ((pos = repl.find(dbl, pos)) != std::string::npos)
boost::replace_all(repl, dbl, newline);
}
- current->Text = repl;
+ current.Text = repl;
}
}
void SubtitleFormat::StripComments(AssFile &file) {
- file.Events.remove_and_dispose_if([](AssEntry const& e) {
- const AssDialogue *diag = dynamic_cast(&e);
- return diag && (diag->Comment || diag->Text.get().empty());
- }, [](AssEntry *e) { delete e; });
+ file.Events.remove_and_dispose_if([](AssDialogue const& diag) {
+ return diag.Comment || diag.Text.get().empty();
+ }, [](AssDialogue *e) { delete e; });
}
-static bool dialog_start_lt(AssEntry &pos, AssDialogue *to_insert) {
- AssDialogue *diag = dynamic_cast(&pos);
- return diag && diag->Start > to_insert->Start;
+static bool dialog_start_lt(AssDialogue &pos, AssDialogue *to_insert) {
+ return pos.Start > to_insert->Start;
}
/// @brief Split and merge lines so there are no overlapping lines
///
/// Algorithm described at http://devel.aegisub.org/wiki/Technical/SplitMerge
void SubtitleFormat::RecombineOverlaps(AssFile &file) {
- entryIter cur, next = file.Events.begin();
- cur = next++;
+ auto next = file.Events.begin();
+ auto cur = next++;
for (; next != file.Events.end(); cur = next++) {
- AssDialogue *prevdlg = dynamic_cast(&*cur);
- AssDialogue *curdlg = dynamic_cast(&*next);
-
- if (!curdlg || !prevdlg) continue;
+ AssDialogue *prevdlg = &*cur;
+ AssDialogue *curdlg = &*next;
if (prevdlg->End <= curdlg->Start) continue;
// Use names like in the algorithm description and prepare for erasing
// old dialogues from the list
- entryIter prev = cur;
+ auto prev = cur;
cur = next;
next++;
@@ -280,20 +274,17 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
/// @brief Merge identical lines that follow each other
void SubtitleFormat::MergeIdentical(AssFile &file) {
- entryIter cur, next = file.Events.begin();
- cur = next++;
+ auto next = file.Events.begin();
+ auto cur = next++;
for (; next != file.Events.end(); cur = next++) {
- AssDialogue *curdlg = dynamic_cast(&*cur);
- AssDialogue *nextdlg = dynamic_cast(&*next);
-
- if (curdlg && nextdlg && curdlg->End == nextdlg->Start && curdlg->Text == nextdlg->Text) {
+ if (cur->End == next->Start && cur->Text == next->Text) {
// Merge timing
- nextdlg->Start = std::min(nextdlg->Start, curdlg->Start);
- nextdlg->End = std::max(nextdlg->End, curdlg->End);
+ next->Start = std::min(next->Start, cur->Start);
+ next->End = std::max(next->End, cur->End);
// Remove duplicate line
- delete curdlg;
+ delete &*cur;
}
}
}
diff --git a/aegisub/src/subtitle_format.h b/aegisub/src/subtitle_format.h
index 3a66f93a8..5d4f847ad 100644
--- a/aegisub/src/subtitle_format.h
+++ b/aegisub/src/subtitle_format.h
@@ -40,7 +40,6 @@
#include
#include
-class AssEntry;
class AssFile;
namespace agi { namespace vfr { class Framerate; } }
diff --git a/aegisub/src/subtitle_format_ass.cpp b/aegisub/src/subtitle_format_ass.cpp
index 898573037..cda8c761b 100644
--- a/aegisub/src/subtitle_format_ass.cpp
+++ b/aegisub/src/subtitle_format_ass.cpp
@@ -1,42 +1,28 @@
-// Copyright (c) 2006, Rodrigo Braz Monteiro
-// All rights reserved.
+// Copyright (c) 2014, Thomas Goyne
//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
+// 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.
//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of the Aegisub Group nor the names of its contributors
-// may be used to endorse or promote products derived from 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.
+// 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/
-/// @file subtitle_format_ass.cpp
-/// @brief Reading/writing of SSA-lineage subtitles
-/// @ingroup subtitle_io
-///
-
#include "config.h"
#include "subtitle_format_ass.h"
+#include "ass_attachment.h"
+#include "ass_dialogue.h"
+#include "ass_info.h"
#include "ass_file.h"
+#include "ass_style.h"
#include "ass_parser.h"
#include "text_file_reader.h"
#include "text_file_writer.h"
@@ -52,17 +38,11 @@ AssSubtitleFormat::AssSubtitleFormat()
}
std::vector AssSubtitleFormat::GetReadWildcards() const {
- std::vector formats;
- formats.push_back("ass");
- formats.push_back("ssa");
- return formats;
+ return {"ass", "ssa"};
}
std::vector AssSubtitleFormat::GetWriteWildcards() const {
- std::vector