From 9b920c78929dc3330db11378ba760624b37f792f Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 23 Aug 2022 15:55:26 +0200 Subject: [PATCH 1/4] folding: Always write fold data to file --- src/subtitle_format_ass.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/subtitle_format_ass.cpp b/src/subtitle_format_ass.cpp index 9117897ab..97fe61060 100644 --- a/src/subtitle_format_ass.cpp +++ b/src/subtitle_format_ass.cpp @@ -108,21 +108,20 @@ struct Writer { WriteIfNotZero("Scroll Position: ", properties.scroll_position); WriteIfNotZero("Active Line: ", properties.active_row); WriteIfNotZero("Video Position: ", properties.video_position); - - std::string foldsdata; - for (LineFold fold : properties.folds) { - if (!foldsdata.empty()) { - foldsdata += ","; - } - foldsdata += std::to_string(fold.start); - foldsdata += ":"; - foldsdata += std::to_string(fold.end); - foldsdata += ":"; - foldsdata += fold.collapsed ? "1" : "0"; - } - - WriteIfNotEmpty("Line Folds: ", foldsdata); } + + std::string foldsdata; + for (LineFold fold : properties.folds) { + if (!foldsdata.empty()) { + foldsdata += ","; + } + foldsdata += std::to_string(fold.start); + foldsdata += ":"; + foldsdata += std::to_string(fold.end); + foldsdata += ":"; + foldsdata += fold.collapsed ? "1" : "0"; + } + WriteIfNotEmpty("Line Folds: ", foldsdata); } void WriteIfNotEmpty(const char *key, std::string const& value) { From c8d4df1355aa7ce3c9aaf1464d517feb5a2218cc Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 23 Aug 2022 16:11:23 +0200 Subject: [PATCH 2/4] Add option to sort subtitles by text --- src/ass_file.cpp | 6 ++++ src/ass_file.h | 4 +++ src/command/grid.cpp | 52 ++++++++++++++++++++++++++++++ src/libresrc/default_menu.json | 4 +++ src/libresrc/osx/default_menu.json | 4 +++ 5 files changed, 70 insertions(+) diff --git a/src/ass_file.cpp b/src/ass_file.cpp index bd06c562e..6fbc0a01c 100644 --- a/src/ass_file.cpp +++ b/src/ass_file.cpp @@ -200,6 +200,12 @@ bool AssFile::CompEffect(AssDialogue const& lft, AssDialogue const& rgt) { bool AssFile::CompLayer(AssDialogue const& lft, AssDialogue const& rgt) { return lft.Layer < rgt.Layer; } +bool AssFile::CompText(AssDialogue const& lft, AssDialogue const& rgt) { + return lft.Text < rgt.Text; +} +bool AssFile::CompTextStripped(AssDialogue const& lft, AssDialogue const& rgt) { + return lft.GetStrippedText() < rgt.GetStrippedText(); +} void AssFile::Sort(CompFunc comp, std::set const& limit) { Sort(Events, comp, limit); diff --git a/src/ass_file.h b/src/ass_file.h index db848cd1e..df09d462a 100644 --- a/src/ass_file.h +++ b/src/ass_file.h @@ -194,6 +194,10 @@ public: static bool CompEffect(AssDialogue const& lft, AssDialogue const& rgt); /// Compare based on layer static bool CompLayer(AssDialogue const& lft, AssDialogue const& rgt); + /// Compare based on text + static bool CompText(AssDialogue const& lft, AssDialogue const& rgt); + /// Compare based on stripped text + static bool CompTextStripped(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. diff --git a/src/command/grid.cpp b/src/command/grid.cpp index d0a9d165b..04d177970 100644 --- a/src/command/grid.cpp +++ b/src/command/grid.cpp @@ -248,6 +248,54 @@ struct grid_sort_style_selected final : public validate_sel_multiple { } }; +struct grid_sort_text final : public Command { + CMD_NAME("grid/sort/text") + STR_MENU("Te&xt") + STR_DISP("Text") + STR_HELP("Sort all subtitles by their text, including styling tags") + + void operator()(agi::Context *c) override { + c->ass->Sort(AssFile::CompText); + c->ass->Commit(_("sort"), AssFile::COMMIT_ORDER); + } +}; + +struct grid_sort_text_selected final : public validate_sel_multiple { + CMD_NAME("grid/sort/text/selected") + STR_MENU("Te&xt") + STR_DISP("Text") + STR_HELP("Sort selected subtitles by their text, including styling tags") + + void operator()(agi::Context *c) override { + c->ass->Sort(AssFile::CompText, c->selectionController->GetSelectedSet()); + c->ass->Commit(_("sort"), AssFile::COMMIT_ORDER); + } +}; + +struct grid_sort_text_stripped final : public Command { + CMD_NAME("grid/sort/text_stripped") + STR_MENU("Stri&pped Text") + STR_DISP("Stripped Text") + STR_HELP("Sort all subtitles by their stripped text") + + void operator()(agi::Context *c) override { + c->ass->Sort(AssFile::CompTextStripped); + c->ass->Commit(_("sort"), AssFile::COMMIT_ORDER); + } +}; + +struct grid_sort_text_stripped_selected final : public validate_sel_multiple { + CMD_NAME("grid/sort/text_stripped/selected") + STR_MENU("Stri&pped Text") + STR_DISP("Stripped Text") + STR_HELP("Sort selected subtitles by their stripped text") + + void operator()(agi::Context *c) override { + c->ass->Sort(AssFile::CompTextStripped, c->selectionController->GetSelectedSet()); + c->ass->Commit(_("sort"), AssFile::COMMIT_ORDER); + } +}; + struct grid_tag_cycle_hiding final : public Command { CMD_NAME("grid/tag/cycle_hiding") CMD_ICON(toggle_tag_hiding) @@ -411,12 +459,16 @@ namespace cmd { reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); diff --git a/src/libresrc/default_menu.json b/src/libresrc/default_menu.json index 36f9c5d22..91ab1348d 100644 --- a/src/libresrc/default_menu.json +++ b/src/libresrc/default_menu.json @@ -109,6 +109,8 @@ { "command" : "grid/sort/style" }, { "command" : "grid/sort/actor" }, { "command" : "grid/sort/effect" }, + { "command" : "grid/sort/text" }, + { "command" : "grid/sort/text_stripped" }, { "command" : "grid/sort/layer" } ], "main/subtitle/sort selected lines" : [ @@ -117,6 +119,8 @@ { "command" : "grid/sort/style/selected" }, { "command" : "grid/sort/actor/selected" }, { "command" : "grid/sort/effect/selected" }, + { "command" : "grid/sort/text/selected" }, + { "command" : "grid/sort/text_stripped/selected" }, { "command" : "grid/sort/layer/selected" } ], "main/timing" : [ diff --git a/src/libresrc/osx/default_menu.json b/src/libresrc/osx/default_menu.json index a05e0f411..d1e039ffa 100644 --- a/src/libresrc/osx/default_menu.json +++ b/src/libresrc/osx/default_menu.json @@ -111,6 +111,8 @@ { "command" : "grid/sort/style" }, { "command" : "grid/sort/actor" }, { "command" : "grid/sort/effect" }, + { "command" : "grid/sort/text" }, + { "command" : "grid/sort/text_stripped" }, { "command" : "grid/sort/layer" } ], "main/subtitle/sort selected lines" : [ @@ -119,6 +121,8 @@ { "command" : "grid/sort/style/selected" }, { "command" : "grid/sort/actor/selected" }, { "command" : "grid/sort/effect/selected" }, + { "command" : "grid/sort/text/selected" }, + { "command" : "grid/sort/text_stripped/selected" }, { "command" : "grid/sort/layer/selected" } ], "main/timing" : [ From c7c874acc4695a652f623bc4bf3b0bea3e8d8d44 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 23 Aug 2022 19:53:40 +0200 Subject: [PATCH 3/4] Add commands to reload audio or video This is mostly useful for reloading Avisyth or VapourSynth scripts. --- src/command/audio.cpp | 12 ++++++++++++ src/command/video.cpp | 12 ++++++++++++ src/project.h | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/command/audio.cpp b/src/command/audio.cpp index 386866775..4b7b72395 100644 --- a/src/command/audio.cpp +++ b/src/command/audio.cpp @@ -128,6 +128,17 @@ struct audio_open_video final : public Command { } }; +struct audio_reload final : public Command { + CMD_NAME("audio/reload") + STR_MENU("Reload Audio") + STR_DISP("Reload Audio") + STR_HELP("Reload the current audio file") + + void operator()(agi::Context *c) override { + c->project->ReloadAudio(); + } +}; + struct audio_view_spectrum final : public Command { CMD_NAME("audio/view/spectrum") STR_MENU("&Spectrum Display") @@ -549,6 +560,7 @@ namespace cmd { reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); + reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); diff --git a/src/command/video.cpp b/src/command/video.cpp index 1a779a52b..bb0444c1b 100644 --- a/src/command/video.cpp +++ b/src/command/video.cpp @@ -612,6 +612,17 @@ struct video_open_dummy final : public Command { } }; +struct video_reload final : public Command { + CMD_NAME("video/reload") + STR_MENU("Reload Video") + STR_DISP("Reload Video") + STR_HELP("Reload the current video file") + + void operator()(agi::Context *c) override { + c->project->ReloadVideo(); + } +}; + struct video_opt_autoscroll final : public Command { CMD_NAME("video/opt/autoscroll") CMD_ICON(toggle_video_autoscroll) @@ -794,6 +805,7 @@ namespace cmd { reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); + reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); diff --git a/src/project.h b/src/project.h index 385a41b4b..090f99d3d 100644 --- a/src/project.h +++ b/src/project.h @@ -60,8 +60,6 @@ class Project { void LoadUnloadFiles(ProjectProperties properties); void UpdateRelativePaths(); - void ReloadAudio(); - void ReloadVideo(); void SetPath(agi::fs::path& var, const char *token, const char *mru, agi::fs::path const& value); @@ -74,11 +72,13 @@ public: bool CanLoadSubtitlesFromVideo() const { return video_has_subtitles; } void LoadAudio(agi::fs::path path); + void ReloadAudio(); void CloseAudio(); agi::AudioProvider *AudioProvider() const { return audio_provider.get(); } agi::fs::path const& AudioName() const { return audio_file; } void LoadVideo(agi::fs::path path); + void ReloadVideo(); void CloseVideo(); AsyncVideoProvider *VideoProvider() const { return video_provider.get(); } agi::fs::path const& VideoName() const { return video_file; } From 9ea7808a30c0a2188623b7cd1742cdbeeebc6c63 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 23 Aug 2022 20:13:45 +0200 Subject: [PATCH 4/4] bestsource: Mark video provider as slow Looks like this wasn't clear enough, so let's make it clear to users that BestVideoSource should only be used if absolutely necessary. --- src/video_provider_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_provider_manager.cpp b/src/video_provider_manager.cpp index 8ec7c18fc..480b31457 100644 --- a/src/video_provider_manager.cpp +++ b/src/video_provider_manager.cpp @@ -50,7 +50,7 @@ namespace { {"Avisynth", CreateAvisynthVideoProvider, false}, #endif #ifdef WITH_BESTSOURCE - {"BestSource", CreateBSVideoProvider, false}, + {"BestSource (SLOW)", CreateBSVideoProvider, false}, #endif }; }