forked from mia/Aegisub
Add range adaptor for filtering to a specific subclass from a heterogeneous range
This makes looping over the subtitle file and parsed dialogue lines less awkward in many cases.
This commit is contained in:
parent
67df64e879
commit
e4d6b8661b
27 changed files with 210 additions and 171 deletions
|
@ -92,6 +92,7 @@
|
||||||
<ClInclude Include="$(SrcDir)include\libaegisub\background_runner.h" />
|
<ClInclude Include="$(SrcDir)include\libaegisub\background_runner.h" />
|
||||||
<ClInclude Include="$(SrcDir)include\libaegisub\color.h" />
|
<ClInclude Include="$(SrcDir)include\libaegisub\color.h" />
|
||||||
<ClInclude Include="$(SrcDir)include\libaegisub\spellchecker.h" />
|
<ClInclude Include="$(SrcDir)include\libaegisub\spellchecker.h" />
|
||||||
|
<ClInclude Include="..\..\libaegisub\include\libaegisub\of_type_adaptor.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="$(SrcDir)windows\lagi_pre.cpp">
|
<ClCompile Include="$(SrcDir)windows\lagi_pre.cpp">
|
||||||
|
|
|
@ -134,6 +134,9 @@
|
||||||
<ClInclude Include="$(SrcDir)common\parser.h">
|
<ClInclude Include="$(SrcDir)common\parser.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\libaegisub\include\libaegisub\of_type_adaptor.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="$(SrcDir)windows\lagi_pre.cpp">
|
<ClCompile Include="$(SrcDir)windows\lagi_pre.cpp">
|
||||||
|
|
69
aegisub/libaegisub/include/libaegisub/of_type_adaptor.h
Normal file
69
aegisub/libaegisub/include/libaegisub/of_type_adaptor.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright (c) 2011, 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 <boost/range/adaptor/filtered.hpp>
|
||||||
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
|
|
||||||
|
namespace agi {
|
||||||
|
namespace of_type_detail {
|
||||||
|
using namespace boost::adaptors;
|
||||||
|
|
||||||
|
/// Tag type returned from of_type<T>() to select the operator| overload
|
||||||
|
template<class T> struct of_type_tag {};
|
||||||
|
|
||||||
|
/// Take the address of a value and dynamic_cast it to Type*
|
||||||
|
template<class Type>
|
||||||
|
struct cast_to {
|
||||||
|
typedef Type *result_type;
|
||||||
|
|
||||||
|
template<class InType> Type *operator()(InType &ptr) const {
|
||||||
|
return dynamic_cast<Type *>(&ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class InType> Type *operator()(InType *ptr) const {
|
||||||
|
return dynamic_cast<Type *>(ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
inline bool not_null(Type *ptr) {
|
||||||
|
return !!ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defined here for ADL reasons, since we don't want the tag type in
|
||||||
|
// the top-level agi namespace (and it lets us get away with the using
|
||||||
|
// namespace above)
|
||||||
|
template<class Rng, class Type>
|
||||||
|
inline auto operator|(Rng& r, of_type_tag<Type>)
|
||||||
|
-> decltype(r | transformed(cast_to<Type>()) | filtered(not_null<Type>))
|
||||||
|
{
|
||||||
|
return r | transformed(cast_to<Type>()) | filtered(not_null<Type>);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const overload of the above
|
||||||
|
template<class Rng, class Type>
|
||||||
|
inline auto operator|(Rng const& r, of_type_tag<Type>)
|
||||||
|
-> decltype(r | transformed(cast_to<const Type>()) | filtered(not_null<const Type>))
|
||||||
|
{
|
||||||
|
return r | transformed(cast_to<const Type>()) | filtered(not_null<const Type>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline of_type_detail::of_type_tag<T> of_type() {
|
||||||
|
return of_type_detail::of_type_tag<T>();
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,6 +58,8 @@
|
||||||
#include "text_file_writer.h"
|
#include "text_file_writer.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template<>
|
template<>
|
||||||
void swap(AssFile &lft, AssFile &rgt) {
|
void swap(AssFile &lft, AssFile &rgt) {
|
||||||
|
@ -399,20 +401,17 @@ void AssFile::GetResolution(int &sw,int &sh) const {
|
||||||
|
|
||||||
wxArrayString AssFile::GetStyles() const {
|
wxArrayString AssFile::GetStyles() const {
|
||||||
wxArrayString styles;
|
wxArrayString styles;
|
||||||
for (auto const& line : Line) {
|
for (auto style : Line | agi::of_type<AssStyle>())
|
||||||
if (const AssStyle *curstyle = dynamic_cast<const AssStyle*>(&line))
|
styles.push_back(style->name);
|
||||||
styles.Add(curstyle->name);
|
|
||||||
}
|
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssStyle *AssFile::GetStyle(wxString const& name) {
|
AssStyle *AssFile::GetStyle(wxString const& name) {
|
||||||
for (auto& line : Line) {
|
for (auto style : Line | agi::of_type<AssStyle>()) {
|
||||||
AssStyle *curstyle = dynamic_cast<AssStyle*>(&line);
|
if (style->name == name)
|
||||||
if (curstyle && curstyle->name == name)
|
return style;
|
||||||
return curstyle;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssFile::AddToRecent(wxString const& file) const {
|
void AssFile::AddToRecent(wxString const& file) const {
|
||||||
|
|
|
@ -63,6 +63,8 @@
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
#include "video_slider.h"
|
#include "video_slider.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GRID_SCROLLBAR = 1730,
|
GRID_SCROLLBAR = 1730,
|
||||||
MENU_SHOW_COL = 1250 // Needs 15 IDs after this
|
MENU_SHOW_COL = 1250 // Needs 15 IDs after this
|
||||||
|
@ -278,12 +280,10 @@ void BaseGrid::UpdateMaps(bool preserve_selected_rows) {
|
||||||
index_line_map.clear();
|
index_line_map.clear();
|
||||||
line_index_map.clear();
|
line_index_map.clear();
|
||||||
|
|
||||||
for (auto& line : context->ass->Line) {
|
for (auto curdiag : context->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
if (AssDialogue *curdiag = dynamic_cast<AssDialogue*>(&line)) {
|
line_index_map[curdiag] = (int)index_line_map.size();
|
||||||
line_index_map[curdiag] = (int)index_line_map.size();
|
index_line_map.push_back(curdiag);
|
||||||
index_line_map.push_back(curdiag);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preserve_selected_rows) {
|
if (preserve_selected_rows) {
|
||||||
Selection sel;
|
Selection sel;
|
||||||
|
|
|
@ -62,6 +62,10 @@
|
||||||
#include "../utils.h"
|
#include "../utils.h"
|
||||||
#include "../video_context.h"
|
#include "../video_context.h"
|
||||||
|
|
||||||
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
using cmd::Command;
|
using cmd::Command;
|
||||||
/// @defgroup cmd-edit Editing commands.
|
/// @defgroup cmd-edit Editing commands.
|
||||||
|
@ -163,14 +167,10 @@ void paste_lines(agi::Context *c, bool paste_over) {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T get_value(AssDialogue const& line, int blockn, T initial, wxString const& tag, wxString alt = wxString()) {
|
T get_value(AssDialogue const& line, int blockn, T initial, wxString const& tag, wxString alt = wxString()) {
|
||||||
for (int i = blockn; i >= 0; i--) {
|
for (auto ovr : line.Blocks | boost::adaptors::reversed | agi::of_type<AssDialogueBlockOverride>()) {
|
||||||
AssDialogueBlockOverride *ovr = dynamic_cast<AssDialogueBlockOverride*>(line.Blocks[i]);
|
for (auto tag : ovr->Tags | boost::adaptors::reversed) {
|
||||||
if (!ovr) continue;
|
if (tag->Name == tag || tag->Name == alt)
|
||||||
|
return tag->Params[0]->Get<T>(initial);
|
||||||
for (int j = (int)ovr->Tags.size() - 1; j >= 0; j--) {
|
|
||||||
if (ovr->Tags[j]->Name == tag || ovr->Tags[j]->Name == alt) {
|
|
||||||
return ovr->Tags[j]->Params[0]->Get<T>(initial);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return initial;
|
return initial;
|
||||||
|
@ -485,9 +485,8 @@ struct edit_find_replace : public Command {
|
||||||
static void copy_lines(agi::Context *c) {
|
static void copy_lines(agi::Context *c) {
|
||||||
wxString data;
|
wxString data;
|
||||||
SubtitleSelection sel = c->selectionController->GetSelectedSet();
|
SubtitleSelection sel = c->selectionController->GetSelectedSet();
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
if (sel.count(diag)) {
|
||||||
if (diag && sel.count(diag)) {
|
|
||||||
if (!data.empty())
|
if (!data.empty())
|
||||||
data += "\r\n";
|
data += "\r\n";
|
||||||
data += diag->GetEntryData();
|
data += diag->GetEntryData();
|
||||||
|
@ -505,10 +504,7 @@ static void delete_lines(agi::Context *c, wxString const& commit_message) {
|
||||||
AssDialogue *new_active = 0;
|
AssDialogue *new_active = 0;
|
||||||
bool hit_active = false;
|
bool hit_active = false;
|
||||||
|
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
|
||||||
if (!diag) continue;
|
|
||||||
|
|
||||||
if (diag == active) {
|
if (diag == active) {
|
||||||
hit_active = true;
|
hit_active = true;
|
||||||
if (new_active) break;
|
if (new_active) break;
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include "../subs_grid.h"
|
#include "../subs_grid.h"
|
||||||
#include "../video_context.h"
|
#include "../video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
using cmd::Command;
|
using cmd::Command;
|
||||||
|
|
||||||
|
@ -71,10 +73,7 @@ namespace {
|
||||||
if (sel.size() < 2) return false;
|
if (sel.size() < 2) return false;
|
||||||
|
|
||||||
size_t found = 0;
|
size_t found = 0;
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
|
||||||
if (!diag) continue;
|
|
||||||
|
|
||||||
if (sel.count(diag)) {
|
if (sel.count(diag)) {
|
||||||
++found;
|
++found;
|
||||||
if (found == sel.size())
|
if (found == sel.size())
|
||||||
|
|
|
@ -53,6 +53,8 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BUTTON_ATTACH_FONT = 1300,
|
BUTTON_ATTACH_FONT = 1300,
|
||||||
BUTTON_ATTACH_GRAPHICS,
|
BUTTON_ATTACH_GRAPHICS,
|
||||||
|
@ -102,14 +104,12 @@ void DialogAttachments::UpdateList() {
|
||||||
listView->InsertColumn(2, _("Group"), wxLIST_FORMAT_LEFT, 100);
|
listView->InsertColumn(2, _("Group"), wxLIST_FORMAT_LEFT, 100);
|
||||||
|
|
||||||
// Fill list
|
// Fill list
|
||||||
for (auto& line : ass->Line) {
|
for (auto attach : ass->Line | agi::of_type<AssAttachment>()) {
|
||||||
if (AssAttachment *attach = dynamic_cast<AssAttachment*>(&line)) {
|
int row = listView->GetItemCount();
|
||||||
int row = listView->GetItemCount();
|
listView->InsertItem(row,attach->GetFileName(true));
|
||||||
listView->InsertItem(row,attach->GetFileName(true));
|
listView->SetItem(row,1,PrettySize(attach->GetSize()));
|
||||||
listView->SetItem(row,1,PrettySize(attach->GetSize()));
|
listView->SetItem(row,2,attach->group);
|
||||||
listView->SetItem(row,2,attach->group);
|
listView->SetItemPtrData(row,wxPtrToUInt(attach));
|
||||||
listView->SetItemPtrData(row,wxPtrToUInt(attach));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include "libresrc/libresrc.h"
|
#include "libresrc/libresrc.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LEFT = 0,
|
LEFT = 0,
|
||||||
RIGHT = 1,
|
RIGHT = 1,
|
||||||
|
@ -206,10 +208,8 @@ namespace {
|
||||||
diag->ParseAssTags();
|
diag->ParseAssTags();
|
||||||
diag->ProcessParameters(resample_tags, state);
|
diag->ProcessParameters(resample_tags, state);
|
||||||
|
|
||||||
for (auto block : diag->Blocks) {
|
for (auto drawing : diag->Blocks | agi::of_type<AssDialogueBlockDrawing>())
|
||||||
if (AssDialogueBlockDrawing *drawing = dynamic_cast<AssDialogueBlockDrawing*>(block))
|
drawing->TransformCoords(state->margin[LEFT], state->margin[TOP], state->rx, state->ry);
|
||||||
drawing->TransformCoords(state->margin[LEFT], state->margin[TOP], state->rx, state->ry);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; ++i)
|
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->Margin[i] = int((diag->Margin[i] + state->margin[i]) * (i < 2 ? state->rx : state->ry) + 0.5);
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include "subs_grid.h"
|
#include "subs_grid.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BUTTON_FIND_NEXT,
|
BUTTON_FIND_NEXT,
|
||||||
BUTTON_REPLACE_NEXT,
|
BUTTON_REPLACE_NEXT,
|
||||||
|
@ -378,11 +380,7 @@ void SearchReplaceEngine::ReplaceAll() {
|
||||||
bool hasSelection = !sel.empty();
|
bool hasSelection = !sel.empty();
|
||||||
bool inSel = affect == 1;
|
bool inSel = affect == 1;
|
||||||
|
|
||||||
// Scan
|
for (auto diag : context->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
for (auto& line : context->ass->Line) {
|
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
|
||||||
if (!diag) continue;
|
|
||||||
|
|
||||||
// Check if row is selected
|
// Check if row is selected
|
||||||
if (inSel && hasSelection && !sel.count(diag))
|
if (inSel && hasSelection && !sel.count(diag))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "selection_controller.h"
|
#include "selection_controller.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ACTION_SET = 0,
|
ACTION_SET = 0,
|
||||||
ACTION_ADD,
|
ACTION_ADD,
|
||||||
|
@ -113,9 +115,7 @@ static std::set<AssDialogue*> process(wxString match_text, bool match_case, int
|
||||||
std::function<bool (wxString)> pred = get_predicate(mode, &re, match_case, match_text);
|
std::function<bool (wxString)> pred = get_predicate(mode, &re, match_case, match_text);
|
||||||
|
|
||||||
std::set<AssDialogue*> matches;
|
std::set<AssDialogue*> matches;
|
||||||
for (auto& line : ass->Line) {
|
for (auto diag : ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
|
||||||
if (!diag) continue;
|
|
||||||
if (diag->Comment && !comments) continue;
|
if (diag->Comment && !comments) continue;
|
||||||
if (!diag->Comment && !dialogue) continue;
|
if (!diag->Comment && !dialogue) continue;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include <libaegisub/io.h>
|
#include <libaegisub/io.h>
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
#include <libaegisub/cajun/elements.h>
|
#include <libaegisub/cajun/elements.h>
|
||||||
#include <libaegisub/cajun/reader.h>
|
#include <libaegisub/cajun/reader.h>
|
||||||
|
@ -352,9 +353,7 @@ void DialogShiftTimes::Process(wxCommandEvent &) {
|
||||||
int block_start = 0;
|
int block_start = 0;
|
||||||
json::Array shifted_blocks;
|
json::Array shifted_blocks;
|
||||||
|
|
||||||
for (auto& entry : context->ass->Line) {
|
for (auto line : context->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *line = dynamic_cast<AssDialogue*>(&entry);
|
|
||||||
if (!line) continue;
|
|
||||||
++row_number;
|
++row_number;
|
||||||
|
|
||||||
if (!sel.count(line)) {
|
if (!sel.count(line)) {
|
||||||
|
|
|
@ -63,6 +63,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "validators.h"
|
#include "validators.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
/// Style rename helper that walks a file searching for a style and optionally
|
/// Style rename helper that walks a file searching for a style and optionally
|
||||||
/// updating references to it
|
/// updating references to it
|
||||||
class StyleRenamer {
|
class StyleRenamer {
|
||||||
|
@ -87,10 +89,7 @@ class StyleRenamer {
|
||||||
found_any = false;
|
found_any = false;
|
||||||
do_replace = replace;
|
do_replace = replace;
|
||||||
|
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
|
||||||
if (!diag) continue;
|
|
||||||
|
|
||||||
if (diag->Style == source_name) {
|
if (diag->Style == source_name) {
|
||||||
if (replace)
|
if (replace)
|
||||||
diag->Style = new_name;
|
diag->Style = new_name;
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
#include "subtitle_format.h"
|
#include "subtitle_format.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -274,11 +276,9 @@ void DialogStyleManager::LoadCurrentStyles(int commit_type) {
|
||||||
CurrentList->Clear();
|
CurrentList->Clear();
|
||||||
styleMap.clear();
|
styleMap.clear();
|
||||||
|
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto style : c->ass->Line | agi::of_type<AssStyle>()) {
|
||||||
if (AssStyle *style = dynamic_cast<AssStyle*>(&line)) {
|
CurrentList->Append(style->name);
|
||||||
CurrentList->Append(style->name);
|
styleMap.push_back(style);
|
||||||
styleMap.push_back(style);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,15 +34,18 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "export_fixstyle.h"
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "export_fixstyle.h"
|
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
AssFixStylesFilter::AssFixStylesFilter()
|
AssFixStylesFilter::AssFixStylesFilter()
|
||||||
: AssExportFilter(_("Fix Styles"), _("Fixes styles by replacing any style that isn't available on file with Default."), -5000, true)
|
: AssExportFilter(_("Fix Styles"), _("Fixes styles by replacing any style that isn't available on file with Default."), -5000, true)
|
||||||
{
|
{
|
||||||
|
@ -53,10 +56,8 @@ void AssFixStylesFilter::ProcessSubs(AssFile *subs, wxWindow *) {
|
||||||
for_each(styles.begin(), styles.end(), std::mem_fun_ref(&wxString::MakeLower));
|
for_each(styles.begin(), styles.end(), std::mem_fun_ref(&wxString::MakeLower));
|
||||||
styles.Sort();
|
styles.Sort();
|
||||||
|
|
||||||
for (auto& line : subs->Line) {
|
for (auto diag : subs->Line | agi::of_type<AssDialogue>()) {
|
||||||
if (AssDialogue *diag = dynamic_cast<AssDialogue*>(&line)) {
|
if (!std::binary_search(styles.begin(), styles.end(), diag->Style.Lower()))
|
||||||
if (!std::binary_search(styles.begin(), styles.end(), diag->Style.Lower()))
|
diag->Style = "Default";
|
||||||
diag->Style = "Default";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
AssTransformFramerateFilter::AssTransformFramerateFilter()
|
AssTransformFramerateFilter::AssTransformFramerateFilter()
|
||||||
: AssExportFilter(_("Transform Framerate"), _("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup."), 1000)
|
: AssExportFilter(_("Transform Framerate"), _("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup."), 1000)
|
||||||
, c(0)
|
, c(0)
|
||||||
|
@ -208,10 +210,7 @@ void AssTransformFramerateFilter::TransformTimeTags(wxString name,int n,AssOverr
|
||||||
|
|
||||||
void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
|
void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
|
||||||
if (!Input->IsLoaded() || !Output->IsLoaded()) return;
|
if (!Input->IsLoaded() || !Output->IsLoaded()) return;
|
||||||
for (auto& entry : subs->Line) {
|
for (auto curDialogue : subs->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *curDialogue = dynamic_cast<AssDialogue*>(&entry);
|
|
||||||
if (!curDialogue) continue;
|
|
||||||
|
|
||||||
line = curDialogue;
|
line = curDialogue;
|
||||||
newK = 0;
|
newK = 0;
|
||||||
oldK = 0;
|
oldK = 0;
|
||||||
|
|
|
@ -68,6 +68,8 @@
|
||||||
#include "validators.h"
|
#include "validators.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template<class T>
|
template<class T>
|
||||||
struct field_setter : public std::binary_function<AssDialogue*, T, void> {
|
struct field_setter : public std::binary_function<AssDialogue*, T, void> {
|
||||||
|
@ -315,10 +317,8 @@ void SubsEditBox::PopulateList(wxComboBox *combo, wxString AssDialogue::*field)
|
||||||
wxEventBlocker blocker(this);
|
wxEventBlocker blocker(this);
|
||||||
|
|
||||||
std::set<wxString> values;
|
std::set<wxString> values;
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>())
|
||||||
if (AssDialogue *diag = dynamic_cast<AssDialogue*>(&line))
|
values.insert(diag->*field);
|
||||||
values.insert(diag->*field);
|
|
||||||
}
|
|
||||||
values.erase("");
|
values.erase("");
|
||||||
wxArrayString arrstr;
|
wxArrayString arrstr;
|
||||||
arrstr.reserve(values.size());
|
arrstr.reserve(values.size());
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
SubtitleFormat::SubtitleFormat(wxString const& name)
|
SubtitleFormat::SubtitleFormat(wxString const& name)
|
||||||
|
@ -164,22 +166,17 @@ agi::vfr::Framerate SubtitleFormat::AskForFPS(bool allow_vfr, bool show_smpte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitleFormat::StripTags(AssFile &file) {
|
void SubtitleFormat::StripTags(AssFile &file) {
|
||||||
for (auto &line : file.Line) {
|
for (auto current : file.Line | agi::of_type<AssDialogue>())
|
||||||
if (AssDialogue *current = dynamic_cast<AssDialogue*>(&line)) {
|
current->StripTags();
|
||||||
current->StripTags();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitleFormat::ConvertNewlines(AssFile &file, wxString const& newline, bool mergeLineBreaks) {
|
void SubtitleFormat::ConvertNewlines(AssFile &file, wxString const& newline, bool mergeLineBreaks) {
|
||||||
for (auto &line : file.Line) {
|
for (auto current : file.Line | agi::of_type<AssDialogue>()) {
|
||||||
if (AssDialogue *current = dynamic_cast<AssDialogue*>(&line)) {
|
current->Text.Replace("\\h", " ");
|
||||||
current->Text.Replace("\\h", " ");
|
current->Text.Replace("\\n", newline);
|
||||||
current->Text.Replace("\\n", newline);
|
current->Text.Replace("\\N", newline);
|
||||||
current->Text.Replace("\\N", newline);
|
if (mergeLineBreaks) {
|
||||||
if (mergeLineBreaks) {
|
while (current->Text.Replace(newline+newline, newline));
|
||||||
while (current->Text.Replace(newline+newline, newline));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <libaegisub/exception.h>
|
#include <libaegisub/exception.h>
|
||||||
#include <libaegisub/io.h>
|
#include <libaegisub/io.h>
|
||||||
#include <libaegisub/line_wrap.h>
|
#include <libaegisub/line_wrap.h>
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
#include <libaegisub/scoped_ptr.h>
|
#include <libaegisub/scoped_ptr.h>
|
||||||
|
|
||||||
#include "aegisub_endian.h"
|
#include "aegisub_endian.h"
|
||||||
|
@ -384,11 +385,8 @@ namespace
|
||||||
subs_list.reserve(copy.Line.size());
|
subs_list.reserve(copy.Line.size());
|
||||||
|
|
||||||
// convert to intermediate format
|
// convert to intermediate format
|
||||||
for (auto& orgline : copy.Line)
|
for (auto line : copy.Line | agi::of_type<AssDialogue>())
|
||||||
{
|
{
|
||||||
AssDialogue *line = dynamic_cast<AssDialogue*>(&orgline);
|
|
||||||
if (!line) continue;
|
|
||||||
|
|
||||||
// add a new subtitle and work on it
|
// add a new subtitle and work on it
|
||||||
subs_list.push_back(EbuSubtitle());
|
subs_list.push_back(EbuSubtitle());
|
||||||
EbuSubtitle &imline = subs_list.back();
|
EbuSubtitle &imline = subs_list.back();
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "text_file_writer.h"
|
#include "text_file_writer.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
EncoreSubtitleFormat::EncoreSubtitleFormat()
|
EncoreSubtitleFormat::EncoreSubtitleFormat()
|
||||||
: SubtitleFormat("Adobe Encore")
|
: SubtitleFormat("Adobe Encore")
|
||||||
{
|
{
|
||||||
|
@ -77,10 +79,8 @@ void EncoreSubtitleFormat::WriteFile(const AssFile *src, wxString const& filenam
|
||||||
// Write lines
|
// Write lines
|
||||||
int i = 0;
|
int i = 0;
|
||||||
TextFileWriter file(filename, "UTF-8");
|
TextFileWriter file(filename, "UTF-8");
|
||||||
for (auto const& line : copy.Line) {
|
for (auto current : copy.Line | agi::of_type<AssDialogue>()) {
|
||||||
if (const AssDialogue *current = dynamic_cast<const AssDialogue*>(&line)) {
|
++i;
|
||||||
++i;
|
file.WriteLineToFile(wxString::Format("%i %s %s %s", i, ft.ToSMPTE(current->Start), ft.ToSMPTE(current->End), current->Text));
|
||||||
file.WriteLineToFile(wxString::Format("%i %s %s %s", i, ft.ToSMPTE(current->Start), ft.ToSMPTE(current->End), current->Text));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include "text_file_writer.h"
|
#include "text_file_writer.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
MicroDVDSubtitleFormat::MicroDVDSubtitleFormat()
|
MicroDVDSubtitleFormat::MicroDVDSubtitleFormat()
|
||||||
: SubtitleFormat("MicroDVD")
|
: SubtitleFormat("MicroDVD")
|
||||||
{
|
{
|
||||||
|
@ -142,12 +144,10 @@ void MicroDVDSubtitleFormat::WriteFile(const AssFile *src, wxString const& filen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write lines
|
// Write lines
|
||||||
for (auto const& line : copy.Line) {
|
for (auto current : copy.Line | agi::of_type<AssDialogue>()) {
|
||||||
if (const AssDialogue *current = dynamic_cast<const AssDialogue*>(&line)) {
|
int start = fps.FrameAtTime(current->Start, agi::vfr::START);
|
||||||
int start = fps.FrameAtTime(current->Start, agi::vfr::START);
|
int end = fps.FrameAtTime(current->End, agi::vfr::END);
|
||||||
int end = fps.FrameAtTime(current->End, agi::vfr::END);
|
|
||||||
|
|
||||||
file.WriteLineToFile(wxString::Format("{%i}{%i}%s", start, end, current->Text));
|
file.WriteLineToFile(wxString::Format("{%i}{%i}%s", start, end, current->Text));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
#include "text_file_reader.h"
|
#include "text_file_reader.h"
|
||||||
#include "text_file_writer.h"
|
#include "text_file_writer.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
DEFINE_SIMPLE_EXCEPTION(SRTParseError, SubtitleFormatParseError, "subtitle_io/parse/srt")
|
DEFINE_SIMPLE_EXCEPTION(SRTParseError, SubtitleFormatParseError, "subtitle_io/parse/srt")
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -508,14 +510,12 @@ void SRTSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Write lines
|
// Write lines
|
||||||
int i=1;
|
int i=0;
|
||||||
for (auto const& line : copy.Line) {
|
for (auto current : copy.Line | agi::of_type<AssDialogue>()) {
|
||||||
if (const AssDialogue *current = dynamic_cast<const AssDialogue*>(&line)) {
|
file.WriteLineToFile(wxString::Format("%d", ++i));
|
||||||
file.WriteLineToFile(wxString::Format("%d", i++));
|
file.WriteLineToFile(WriteSRTTime(current->Start) + " --> " + WriteSRTTime(current->End));
|
||||||
file.WriteLineToFile(WriteSRTTime(current->Start) + " --> " + WriteSRTTime(current->End));
|
file.WriteLineToFile(ConvertTags(current));
|
||||||
file.WriteLineToFile(ConvertTags(current));
|
file.WriteLineToFile("");
|
||||||
file.WriteLineToFile("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,10 +536,7 @@ bool SRTSubtitleFormat::CanSave(const AssFile *file) const {
|
||||||
// Check dialogue
|
// Check dialogue
|
||||||
if (const AssDialogue *curdiag = dynamic_cast<const AssDialogue*>(&line)) {
|
if (const AssDialogue *curdiag = dynamic_cast<const AssDialogue*>(&line)) {
|
||||||
std::vector<AssDialogueBlock*> blocks = curdiag->ParseTags();
|
std::vector<AssDialogueBlock*> blocks = curdiag->ParseTags();
|
||||||
for (auto block : blocks) {
|
for (auto ovr : blocks | agi::of_type<AssDialogueBlockOverride>()) {
|
||||||
AssDialogueBlockOverride *ovr = dynamic_cast<AssDialogueBlockOverride*>(block);
|
|
||||||
if (!ovr) continue;
|
|
||||||
|
|
||||||
// Verify that all overrides used are supported
|
// Verify that all overrides used are supported
|
||||||
for (auto tag : ovr->Tags) {
|
for (auto tag : ovr->Tags) {
|
||||||
if (!std::binary_search(supported_tags, std::end(supported_tags), tag->Name)) {
|
if (!std::binary_search(supported_tags, std::end(supported_tags), tag->Name)) {
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "ass_time.h"
|
#include "ass_time.h"
|
||||||
#include "text_file_writer.h"
|
#include "text_file_writer.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
TranStationSubtitleFormat::TranStationSubtitleFormat()
|
TranStationSubtitleFormat::TranStationSubtitleFormat()
|
||||||
: SubtitleFormat("TranStation")
|
: SubtitleFormat("TranStation")
|
||||||
{
|
{
|
||||||
|
@ -75,16 +77,13 @@ void TranStationSubtitleFormat::WriteFile(const AssFile *src, wxString const& fi
|
||||||
SmpteFormatter ft(fps);
|
SmpteFormatter ft(fps);
|
||||||
TextFileWriter file(filename, encoding);
|
TextFileWriter file(filename, encoding);
|
||||||
AssDialogue *prev = 0;
|
AssDialogue *prev = 0;
|
||||||
for (auto& line : copy.Line) {
|
for (auto cur : copy.Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *cur = dynamic_cast<AssDialogue*>(&line);
|
if (prev) {
|
||||||
|
|
||||||
if (prev && cur) {
|
|
||||||
file.WriteLineToFile(ConvertLine(©, prev, fps, ft, cur->Start));
|
file.WriteLineToFile(ConvertLine(©, prev, fps, ft, cur->Start));
|
||||||
file.WriteLineToFile("");
|
file.WriteLineToFile("");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur)
|
prev = cur;
|
||||||
prev = cur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// flush last line
|
// flush last line
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
|
||||||
DEFINE_SIMPLE_EXCEPTION(TTXTParseError, SubtitleFormatParseError, "subtitle_io/parse/ttxt")
|
DEFINE_SIMPLE_EXCEPTION(TTXTParseError, SubtitleFormatParseError, "subtitle_io/parse/ttxt")
|
||||||
|
|
||||||
TTXTSubtitleFormat::TTXTSubtitleFormat()
|
TTXTSubtitleFormat::TTXTSubtitleFormat()
|
||||||
|
@ -176,14 +179,9 @@ void TTXTSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
||||||
|
|
||||||
// Create lines
|
// Create lines
|
||||||
const AssDialogue *prev = 0;
|
const AssDialogue *prev = 0;
|
||||||
for (auto const& line : copy.Line) {
|
for (auto current : copy.Line | agi::of_type<AssDialogue>()) {
|
||||||
const AssDialogue *current = dynamic_cast<const AssDialogue*>(&line);
|
WriteLine(root, prev, current);
|
||||||
if (current && !current->Comment) {
|
prev = current;
|
||||||
WriteLine(root, prev, current);
|
|
||||||
prev = current;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw TTXTParseError("Unexpected line type in TTXT file", 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save XML
|
// Save XML
|
||||||
|
@ -268,11 +266,9 @@ void TTXTSubtitleFormat::ConvertToTTXT(AssFile &file) const {
|
||||||
|
|
||||||
// Find last line
|
// Find last line
|
||||||
AssTime lastTime;
|
AssTime lastTime;
|
||||||
for (EntryList::reverse_iterator cur = file.Line.rbegin(); cur != file.Line.rend(); ++cur) {
|
for (auto line : file.Line | boost::adaptors::reversed | agi::of_type<AssDialogue>()) {
|
||||||
if (AssDialogue *prev = dynamic_cast<AssDialogue*>(&*cur)) {
|
lastTime = line->End;
|
||||||
lastTime = prev->End;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert blank line at the end
|
// Insert blank line at the end
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
TXTSubtitleFormat::TXTSubtitleFormat()
|
TXTSubtitleFormat::TXTSubtitleFormat()
|
||||||
: SubtitleFormat("Plain-Text")
|
: SubtitleFormat("Plain-Text")
|
||||||
{
|
{
|
||||||
|
@ -129,9 +131,8 @@ void TXTSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
||||||
size_t num_actor_names = 0, num_dialogue_lines = 0;
|
size_t num_actor_names = 0, num_dialogue_lines = 0;
|
||||||
|
|
||||||
// Detect number of lines with Actor field filled out
|
// Detect number of lines with Actor field filled out
|
||||||
for (auto const& line : src->Line) {
|
for (auto dia : src->Line | agi::of_type<AssDialogue>()) {
|
||||||
const AssDialogue *dia = dynamic_cast<const AssDialogue*>(&line);
|
if (!dia->Comment) {
|
||||||
if (dia && !dia->Comment) {
|
|
||||||
num_dialogue_lines++;
|
num_dialogue_lines++;
|
||||||
if (!dia->Actor.empty())
|
if (!dia->Actor.empty())
|
||||||
num_actor_names++;
|
num_actor_names++;
|
||||||
|
@ -146,10 +147,7 @@ void TXTSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
||||||
file.WriteLineToFile(wxString("# Exported by Aegisub ") + GetAegisubShortVersionString());
|
file.WriteLineToFile(wxString("# Exported by Aegisub ") + GetAegisubShortVersionString());
|
||||||
|
|
||||||
// Write the file
|
// Write the file
|
||||||
for (auto const& line : src->Line) {
|
for (auto dia : src->Line | agi::of_type<AssDialogue>()) {
|
||||||
const AssDialogue *dia = dynamic_cast<const AssDialogue*>(&line);
|
|
||||||
if (!dia) continue;
|
|
||||||
|
|
||||||
wxString out_line;
|
wxString out_line;
|
||||||
|
|
||||||
if (dia->Comment)
|
if (dia->Comment)
|
||||||
|
@ -161,10 +159,8 @@ void TXTSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename,
|
||||||
wxString out_text;
|
wxString out_text;
|
||||||
if (strip_formatting) {
|
if (strip_formatting) {
|
||||||
std::vector<AssDialogueBlock*> blocks = dia->ParseTags();
|
std::vector<AssDialogueBlock*> blocks = dia->ParseTags();
|
||||||
for (auto block : blocks) {
|
for (auto block : blocks | agi::of_type<AssDialogueBlockPlain>())
|
||||||
if (block->GetType() == BLOCK_PLAIN)
|
out_text += block->GetText();
|
||||||
out_text += block->GetText();
|
|
||||||
}
|
|
||||||
delete_clear(blocks);
|
delete_clear(blocks);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -42,10 +42,7 @@
|
||||||
#include "visual_tool_drag.h"
|
#include "visual_tool_drag.h"
|
||||||
#include "visual_tool_vector_clip.h"
|
#include "visual_tool_vector_clip.h"
|
||||||
|
|
||||||
template<class C, class F>
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
static void for_each(C &range, F func) {
|
|
||||||
std::for_each(range.begin(), range.end(), func);
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::placeholders::_1;
|
using std::placeholders::_1;
|
||||||
|
|
||||||
|
@ -218,9 +215,10 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
// continue drag
|
// continue drag
|
||||||
if (event.LeftIsDown()) {
|
if (event.LeftIsDown()) {
|
||||||
for_each(sel_features, std::bind(&FeatureType::UpdateDrag, _1,
|
for (auto sel : sel_features)
|
||||||
mouse_pos - drag_start, shift_down));
|
sel->UpdateDrag(mouse_pos - drag_start, shift_down);
|
||||||
for_each(sel_features, std::bind(&VisualTool<FeatureType>::UpdateDrag, this, _1));
|
for (auto sel : sel_features)
|
||||||
|
UpdateDrag(sel);
|
||||||
Commit();
|
Commit();
|
||||||
need_render = true;
|
need_render = true;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +271,7 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
|
||||||
c->selectionController->SetActiveLine(active_feature->line);
|
c->selectionController->SetActiveLine(active_feature->line);
|
||||||
|
|
||||||
if (InitializeDrag(active_feature)) {
|
if (InitializeDrag(active_feature)) {
|
||||||
for_each(sel_features, std::bind(&VisualDraggableFeature::StartDrag, _1));
|
for (auto sel : sel_features) sel->StartDrag();
|
||||||
dragging = true;
|
dragging = true;
|
||||||
parent->CaptureMouse();
|
parent->CaptureMouse();
|
||||||
}
|
}
|
||||||
|
@ -370,10 +368,7 @@ struct scoped_tag_parse {
|
||||||
|
|
||||||
// Find a tag's parameters in a line or return NULL if it's not found
|
// Find a tag's parameters in a line or return NULL if it's not found
|
||||||
static param_vec find_tag(const AssDialogue *line, wxString tag_name) {
|
static param_vec find_tag(const AssDialogue *line, wxString tag_name) {
|
||||||
for (auto block : line->Blocks) {
|
for (auto ovr : line->Blocks | agi::of_type<AssDialogueBlockOverride>()) {
|
||||||
const AssDialogueBlockOverride *ovr = dynamic_cast<const AssDialogueBlockOverride*>(block);
|
|
||||||
if (!ovr) continue;
|
|
||||||
|
|
||||||
for (auto tag : ovr->Tags) {
|
for (auto tag : ovr->Tags) {
|
||||||
if (tag->Name == tag_name)
|
if (tag->Name == tag_name)
|
||||||
return &tag->Params;
|
return &tag->Params;
|
||||||
|
@ -552,8 +547,8 @@ wxString VisualToolBase::GetLineVectorClip(AssDialogue *diag, int &scale, bool &
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolBase::SetSelectedOverride(wxString const& tag, wxString const& value) {
|
void VisualToolBase::SetSelectedOverride(wxString const& tag, wxString const& value) {
|
||||||
for_each(c->selectionController->GetSelectedSet(),
|
for (auto line : c->selectionController->GetSelectedSet())
|
||||||
std::bind(&VisualToolBase::SetOverride, this, _1, tag, value));
|
SetOverride(line, tag, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolBase::SetOverride(AssDialogue* line, wxString const& tag, wxString const& value) {
|
void VisualToolBase::SetOverride(AssDialogue* line, wxString const& tag, wxString const& value) {
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
#include "video_display.h"
|
#include "video_display.h"
|
||||||
|
|
||||||
|
#include <libaegisub/of_type_adaptor.h>
|
||||||
|
|
||||||
static const DraggableFeatureType DRAG_ORIGIN = DRAG_BIG_TRIANGLE;
|
static const DraggableFeatureType DRAG_ORIGIN = DRAG_BIG_TRIANGLE;
|
||||||
static const DraggableFeatureType DRAG_START = DRAG_BIG_SQUARE;
|
static const DraggableFeatureType DRAG_START = DRAG_BIG_SQUARE;
|
||||||
static const DraggableFeatureType DRAG_END = DRAG_BIG_CIRCLE;
|
static const DraggableFeatureType DRAG_END = DRAG_BIG_CIRCLE;
|
||||||
|
@ -114,9 +116,8 @@ void VisualToolDrag::OnFileChanged() {
|
||||||
primary = 0;
|
primary = 0;
|
||||||
active_feature = features.end();
|
active_feature = features.end();
|
||||||
|
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
if (IsDisplayed(diag))
|
||||||
if (diag && IsDisplayed(diag))
|
|
||||||
MakeFeatures(diag);
|
MakeFeatures(diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +131,7 @@ void VisualToolDrag::OnFrameChanged() {
|
||||||
feature_iterator feat = features.begin();
|
feature_iterator feat = features.begin();
|
||||||
feature_iterator end = features.end();
|
feature_iterator end = features.end();
|
||||||
|
|
||||||
for (auto& line : c->ass->Line) {
|
for (auto diag : c->ass->Line | agi::of_type<AssDialogue>()) {
|
||||||
AssDialogue *diag = dynamic_cast<AssDialogue*>(&line);
|
|
||||||
if (!diag) continue;
|
|
||||||
|
|
||||||
if (IsDisplayed(diag)) {
|
if (IsDisplayed(diag)) {
|
||||||
// Features don't exist and should
|
// Features don't exist and should
|
||||||
if (feat == end || feat->line != diag)
|
if (feat == end || feat->line != diag)
|
||||||
|
|
Loading…
Reference in a new issue