mirror of https://github.com/odrling/Aegisub
Add a box with the character count of the longest line
Character counts are a pretty terrible measure of anything, but it's still the main measure of length used in most subtitling standards (because subtitling standards are written under the assumption that the tools are terrible (which is generally an accurate assumption)).
This commit is contained in:
parent
1b15a753a1
commit
422cfb153f
|
@ -349,6 +349,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"Subtitle" : {
|
"Subtitle" : {
|
||||||
|
"Character Limit" : 40,
|
||||||
"Default Resolution" : {
|
"Default Resolution" : {
|
||||||
"Auto" : true,
|
"Auto" : true,
|
||||||
"Height" : 720,
|
"Height" : 720,
|
||||||
|
|
|
@ -349,6 +349,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"Subtitle" : {
|
"Subtitle" : {
|
||||||
|
"Character Limit" : 40,
|
||||||
"Default Resolution" : {
|
"Default Resolution" : {
|
||||||
"Auto" : true,
|
"Auto" : true,
|
||||||
"Height" : 720,
|
"Height" : 720,
|
||||||
|
|
|
@ -199,6 +199,7 @@ 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 *grid = PageSizer(_("Grid"));
|
wxFlexGridSizer *grid = PageSizer(_("Grid"));
|
||||||
OptionAdd(grid, _("Allow grid to take focus"), "Subtitle/Grid/Focus Allow");
|
OptionAdd(grid, _("Allow grid to take focus"), "Subtitle/Grid/Focus Allow");
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <wx/checkbox.h>
|
#include <wx/checkbox.h>
|
||||||
#include <wx/combobox.h>
|
#include <wx/combobox.h>
|
||||||
#include <wx/radiobut.h>
|
#include <wx/radiobut.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/spinctrl.h>
|
#include <wx/spinctrl.h>
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "command/command.h"
|
#include "command/command.h"
|
||||||
|
#include "compat.h"
|
||||||
#include "dialog_search_replace.h"
|
#include "dialog_search_replace.h"
|
||||||
#include "include/aegisub/context.h"
|
#include "include/aegisub/context.h"
|
||||||
#include "include/aegisub/hotkey.h"
|
#include "include/aegisub/hotkey.h"
|
||||||
|
@ -120,6 +122,10 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
|
||||||
Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &SubsEditBox::OnEffectChange, this, Effect->GetId());
|
Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &SubsEditBox::OnEffectChange, this, Effect->GetId());
|
||||||
TopSizer->Add(Effect, 3, wxALIGN_CENTER, 5);
|
TopSizer->Add(Effect, 3, wxALIGN_CENTER, 5);
|
||||||
|
|
||||||
|
CharCount = new wxTextCtrl(this, -1, "0", wxDefaultPosition, wxSize(30, -1), wxTE_READONLY | wxTE_CENTER);
|
||||||
|
CharCount->SetToolTip(_("Number of characters in the longest line of this subtitle."));
|
||||||
|
TopSizer->Add(CharCount, 0, wxALIGN_CENTER, 5);
|
||||||
|
|
||||||
// Middle controls
|
// Middle controls
|
||||||
MiddleSizer = new wxBoxSizer(wxHORIZONTAL);
|
MiddleSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
|
@ -287,6 +293,7 @@ void SubsEditBox::OnCommit(int type) {
|
||||||
|
|
||||||
if (type & AssFile::COMMIT_DIAG_TEXT) {
|
if (type & AssFile::COMMIT_DIAG_TEXT) {
|
||||||
TextEdit->SetTextTo(line->Text);
|
TextEdit->SetTextTo(line->Text);
|
||||||
|
UpdateCharacterCount(line->Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type & AssFile::COMMIT_DIAG_META) {
|
if (type & AssFile::COMMIT_DIAG_META) {
|
||||||
|
@ -375,6 +382,7 @@ void SubsEditBox::OnChange(wxStyledTextEvent &event) {
|
||||||
if (event.GetModificationType() & wxSTC_STARTACTION)
|
if (event.GetModificationType() & wxSTC_STARTACTION)
|
||||||
commitId = -1;
|
commitId = -1;
|
||||||
CommitText(_("modify text"));
|
CommitText(_("modify text"));
|
||||||
|
UpdateCharacterCount(line->Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,3 +522,13 @@ void SubsEditBox::CallCommand(const char *cmd_name) {
|
||||||
cmd::call(cmd_name, c);
|
cmd::call(cmd_name, c);
|
||||||
TextEdit->SetFocus();
|
TextEdit->SetFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SubsEditBox::UpdateCharacterCount(wxString const& text) {
|
||||||
|
size_t length = MaxLineLength(text);
|
||||||
|
CharCount->SetValue(wxString::Format("%lu", (unsigned long)length));
|
||||||
|
size_t limit = (size_t)OPT_GET("Subtitle/Character Limit")->GetInt();
|
||||||
|
if (limit && length > limit)
|
||||||
|
CharCount->SetBackgroundColour(to_wx(OPT_GET("Colour/Subtitle/Syntax/Background/Error")->GetColor()));
|
||||||
|
else
|
||||||
|
CharCount->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||||
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ class SubsEditBox : public wxPanel {
|
||||||
Placeholder<wxComboBox> *Effect;
|
Placeholder<wxComboBox> *Effect;
|
||||||
wxRadioButton *ByTime;
|
wxRadioButton *ByTime;
|
||||||
wxRadioButton *ByFrame;
|
wxRadioButton *ByFrame;
|
||||||
|
wxTextCtrl *CharCount;
|
||||||
|
|
||||||
wxSizer *TopSizer;
|
wxSizer *TopSizer;
|
||||||
wxSizer *MiddleBotSizer;
|
wxSizer *MiddleBotSizer;
|
||||||
|
@ -184,6 +185,9 @@ class SubsEditBox : public wxPanel {
|
||||||
/// @brief Enable or disable frame timing mode
|
/// @brief Enable or disable frame timing mode
|
||||||
void UpdateFrameTiming(agi::vfr::Framerate const& fps);
|
void UpdateFrameTiming(agi::vfr::Framerate const& fps);
|
||||||
|
|
||||||
|
/// Update the character count box for the given text
|
||||||
|
void UpdateCharacterCount(wxString const& text);
|
||||||
|
|
||||||
/// Call a command the restore focus to the edit box
|
/// Call a command the restore focus to the edit box
|
||||||
void CallCommand(const char *cmd_name);
|
void CallCommand(const char *cmd_name);
|
||||||
|
|
||||||
|
|
|
@ -391,6 +391,51 @@ void CleanCache(wxString const& directory, wxString const& file_type, int64_t ma
|
||||||
LOG_D("utils/clean_cache") << "thread started successfully";
|
LOG_D("utils/clean_cache") << "thread started successfully";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t MaxLineLength(wxString const& text) {
|
||||||
|
size_t max_line_length = 0;
|
||||||
|
size_t current_line_length = 0;
|
||||||
|
bool last_was_slash = false;
|
||||||
|
bool in_ovr = false;
|
||||||
|
|
||||||
|
for (auto const& c : text) {
|
||||||
|
if (in_ovr) {
|
||||||
|
in_ovr = c != '}';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\\') {
|
||||||
|
current_line_length += last_was_slash; // for the slash before this one
|
||||||
|
last_was_slash = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_was_slash) {
|
||||||
|
last_was_slash = false;
|
||||||
|
if (c == 'h') {
|
||||||
|
++current_line_length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 'n' || c == 'N') {
|
||||||
|
max_line_length = std::max(max_line_length, current_line_length);
|
||||||
|
current_line_length = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not actually an escape so add the character for the slash and fall through
|
||||||
|
++current_line_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '{')
|
||||||
|
in_ovr = true;
|
||||||
|
else
|
||||||
|
++current_line_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_line_length += last_was_slash;
|
||||||
|
return std::max(max_line_length, current_line_length);
|
||||||
|
}
|
||||||
|
|
||||||
// OS X implementation in osx_utils.mm
|
// OS X implementation in osx_utils.mm
|
||||||
#ifndef __WXOSX_COCOA__
|
#ifndef __WXOSX_COCOA__
|
||||||
void AddFullScreenButton(wxWindow *) { }
|
void AddFullScreenButton(wxWindow *) { }
|
||||||
|
|
|
@ -74,6 +74,9 @@ bool StringEmptyOrWhitespace(const wxString &str);
|
||||||
int AegiStringToInt(const wxString &str,int start=0,int end=-1);
|
int AegiStringToInt(const wxString &str,int start=0,int end=-1);
|
||||||
int AegiStringToFix(const wxString &str,size_t decimalPlaces,int start=0,int end=-1);
|
int AegiStringToFix(const wxString &str,size_t decimalPlaces,int start=0,int end=-1);
|
||||||
|
|
||||||
|
/// Get the length in characters of the longest line in the given text
|
||||||
|
size_t MaxLineLength(wxString const& text);
|
||||||
|
|
||||||
/// @brief Launch a new copy of Aegisub.
|
/// @brief Launch a new copy of Aegisub.
|
||||||
///
|
///
|
||||||
/// Contrary to what the name suggests, this does not close the currently
|
/// Contrary to what the name suggests, this does not close the currently
|
||||||
|
|
Loading…
Reference in New Issue