forked from mia/Aegisub
Add an option to ignore whitespace for the character counter
This commit is contained in:
parent
ac09590389
commit
d81e2f45ac
6 changed files with 49 additions and 25 deletions
|
@ -350,6 +350,9 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"Subtitle" : {
|
"Subtitle" : {
|
||||||
|
"Character Counter" : {
|
||||||
|
"Ignore Whitespace" : false
|
||||||
|
},
|
||||||
"Character Limit" : 40,
|
"Character Limit" : 40,
|
||||||
"Default Resolution" : {
|
"Default Resolution" : {
|
||||||
"Auto" : true,
|
"Auto" : true,
|
||||||
|
|
|
@ -350,6 +350,9 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"Subtitle" : {
|
"Subtitle" : {
|
||||||
|
"Character Counter" : {
|
||||||
|
"Ignore Whitespace" : false
|
||||||
|
},
|
||||||
"Character Limit" : 40,
|
"Character Limit" : 40,
|
||||||
"Default Resolution" : {
|
"Default Resolution" : {
|
||||||
"Auto" : true,
|
"Auto" : true,
|
||||||
|
|
|
@ -18,24 +18,6 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
#include <wx/checkbox.h>
|
|
||||||
#include <wx/combobox.h>
|
|
||||||
#include <wx/event.h>
|
|
||||||
#include <wx/filefn.h>
|
|
||||||
#include <wx/listctrl.h>
|
|
||||||
#include <wx/msgdlg.h>
|
|
||||||
#include <wx/srchctrl.h>
|
|
||||||
#include <wx/sizer.h>
|
|
||||||
#include <wx/spinctrl.h>
|
|
||||||
#include <wx/stattext.h>
|
|
||||||
#include <wx/treebook.h>
|
|
||||||
#include <wx/treebook.h>
|
|
||||||
|
|
||||||
#include <libaegisub/exception.h>
|
|
||||||
#include <libaegisub/hotkey.h>
|
|
||||||
|
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
|
||||||
#include "audio_renderer_waveform.h"
|
#include "audio_renderer_waveform.h"
|
||||||
|
@ -61,6 +43,23 @@
|
||||||
#include <ffms.h>
|
#include <ffms.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <libaegisub/exception.h>
|
||||||
|
#include <libaegisub/hotkey.h>
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <wx/checkbox.h>
|
||||||
|
#include <wx/combobox.h>
|
||||||
|
#include <wx/event.h>
|
||||||
|
#include <wx/filefn.h>
|
||||||
|
#include <wx/listctrl.h>
|
||||||
|
#include <wx/msgdlg.h>
|
||||||
|
#include <wx/srchctrl.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/treebook.h>
|
||||||
|
|
||||||
#define CLASS_PAGE(name) \
|
#define CLASS_PAGE(name) \
|
||||||
class name: public OptionPage { \
|
class name: public OptionPage { \
|
||||||
public: \
|
public: \
|
||||||
|
@ -192,7 +191,10 @@ Interface::Interface(wxTreebook *book, Preferences *parent): OptionPage(book, pa
|
||||||
OptionAdd(edit_box, _("Enable syntax highlighting"), "Subtitle/Highlight/Syntax");
|
OptionAdd(edit_box, _("Enable syntax highlighting"), "Subtitle/Highlight/Syntax");
|
||||||
OptionBrowse(edit_box, _("Dictionaries path"), "Path/Dictionary");
|
OptionBrowse(edit_box, _("Dictionaries path"), "Path/Dictionary");
|
||||||
OptionFont(edit_box, "Subtitle/Edit Box/");
|
OptionFont(edit_box, "Subtitle/Edit Box/");
|
||||||
OptionAdd(edit_box, _("Maximum characters per line"), "Subtitle/Character Limit", 0, 1000);
|
|
||||||
|
wxFlexGridSizer *character_count = PageSizer(_("Character Counter"));
|
||||||
|
OptionAdd(character_count, _("Maximum characters per line"), "Subtitle/Character Limit", 0, 1000);
|
||||||
|
OptionAdd(character_count, _("Ignore whitespace"), "Subtitle/Character Counter/Ignore Whitespace");
|
||||||
|
|
||||||
wxFlexGridSizer *grid = PageSizer(_("Grid"));
|
wxFlexGridSizer *grid = PageSizer(_("Grid"));
|
||||||
OptionAdd(grid, _("Focus grid on click"), "Subtitle/Grid/Focus Allow");
|
OptionAdd(grid, _("Focus grid on click"), "Subtitle/Grid/Focus Allow");
|
||||||
|
|
|
@ -577,8 +577,9 @@ void SubsEditBox::CallCommand(const char *cmd_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsEditBox::UpdateCharacterCount(std::string const& text) {
|
void SubsEditBox::UpdateCharacterCount(std::string const& text) {
|
||||||
|
auto ignore_whitespace = OPT_GET("Subtitle/Character Counter/Ignore Whitespace")->GetBool();
|
||||||
agi::dispatch::Background().Async([=]{
|
agi::dispatch::Background().Async([=]{
|
||||||
size_t length = MaxLineLength(text);
|
size_t length = MaxLineLength(text, ignore_whitespace);
|
||||||
agi::dispatch::Main().Async([=]{
|
agi::dispatch::Main().Async([=]{
|
||||||
char_count->SetValue(wxString::Format("%lu", (unsigned long)length));
|
char_count->SetValue(wxString::Format("%lu", (unsigned long)length));
|
||||||
size_t limit = (size_t)OPT_GET("Subtitle/Character Limit")->GetInt();
|
size_t limit = (size_t)OPT_GET("Subtitle/Character Limit")->GetInt();
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
#include <boost/locale/boundary.hpp>
|
#include <boost/locale/boundary.hpp>
|
||||||
#include <boost/range/algorithm_ext.hpp>
|
#include <boost/range/algorithm_ext.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unicode/uchar.h>
|
||||||
|
#include <unicode/utf8.h>
|
||||||
|
|
||||||
#include <wx/clipbrd.h>
|
#include <wx/clipbrd.h>
|
||||||
#include <wx/filedlg.h>
|
#include <wx/filedlg.h>
|
||||||
|
@ -222,7 +224,7 @@ void CleanCache(agi::fs::path const& directory, std::string const& file_type, ui
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MaxLineLength(std::string const& text) {
|
size_t MaxLineLength(std::string const& text, bool ignore_whitespace) {
|
||||||
auto tokens = agi::ass::TokenizeDialogueBody(text);
|
auto tokens = agi::ass::TokenizeDialogueBody(text);
|
||||||
agi::ass::MarkDrawings(text, tokens);
|
agi::ass::MarkDrawings(text, tokens);
|
||||||
|
|
||||||
|
@ -231,8 +233,10 @@ size_t MaxLineLength(std::string const& text) {
|
||||||
size_t current_line_length = 0;
|
size_t current_line_length = 0;
|
||||||
for (auto token : tokens) {
|
for (auto token : tokens) {
|
||||||
if (token.type == agi::ass::DialogueTokenType::LINE_BREAK) {
|
if (token.type == agi::ass::DialogueTokenType::LINE_BREAK) {
|
||||||
if (text[pos + 1] == 'h')
|
if (text[pos + 1] == 'h') {
|
||||||
|
if (!ignore_whitespace)
|
||||||
current_line_length += 1;
|
current_line_length += 1;
|
||||||
|
}
|
||||||
else { // N or n
|
else { // N or n
|
||||||
max_line_length = std::max(max_line_length, current_line_length);
|
max_line_length = std::max(max_line_length, current_line_length);
|
||||||
current_line_length = 0;
|
current_line_length = 0;
|
||||||
|
@ -241,7 +245,18 @@ size_t MaxLineLength(std::string const& text) {
|
||||||
else if (token.type == agi::ass::DialogueTokenType::TEXT) {
|
else if (token.type == agi::ass::DialogueTokenType::TEXT) {
|
||||||
using namespace boost::locale::boundary;
|
using namespace boost::locale::boundary;
|
||||||
const ssegment_index characters(character, begin(text) + pos, begin(text) + pos + token.length);
|
const ssegment_index characters(character, begin(text) + pos, begin(text) + pos + token.length);
|
||||||
|
if (!ignore_whitespace)
|
||||||
current_line_length += boost::distance(characters);
|
current_line_length += boost::distance(characters);
|
||||||
|
else {
|
||||||
|
// characters.rule(word_any) doesn't seem to work for character indexes (everything is word_none)
|
||||||
|
for (auto const& chr : characters) {
|
||||||
|
UChar32 c;
|
||||||
|
int i = 0;
|
||||||
|
U8_NEXT_UNSAFE(chr.begin(), i, c);
|
||||||
|
if (!u_isUWhiteSpace(c))
|
||||||
|
++current_line_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += token.length;
|
pos += token.length;
|
||||||
|
|
|
@ -62,7 +62,7 @@ void StatusTimeout(wxString const& msg, int ms = 10000);
|
||||||
int SmallestPowerOf2(int x);
|
int SmallestPowerOf2(int x);
|
||||||
|
|
||||||
/// Get the length in characters of the longest line in the given text
|
/// Get the length in characters of the longest line in the given text
|
||||||
size_t MaxLineLength(std::string const& text);
|
size_t MaxLineLength(std::string const& text, bool ignore_whitespace);
|
||||||
|
|
||||||
/// @brief Launch a new copy of Aegisub.
|
/// @brief Launch a new copy of Aegisub.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in a new issue