Added a non-overwrite mode for text edit controls, which can be set on the menu. Some basic testing was done, but not exhaustive, which means that it MIGHT be buggy (also, the old mode might have been bugged)

Originally committed to SVN as r1295.
This commit is contained in:
Rodrigo Braz Monteiro 2007-06-23 06:07:32 +00:00
parent 69bb371305
commit 54f5c82296
9 changed files with 215 additions and 164 deletions

View File

@ -59,20 +59,42 @@ void AssTime::ParseASS (const wxString text) {
// Prepare
size_t pos = 0;
size_t end = 0;
long th,tm,tms;
long th=0,tm=0,tms=0;
// Count the number of colons
size_t len = text.Length();
int colons = 0;
for (pos=0;pos<len;pos++) if (text[pos] == _T(':')) colons++;
pos = 0;
// Set start so that there are only two colons at most
if (colons > 2) {
for (pos=0;pos<len;pos++) {
if (text[pos] == _T(':')) {
colons--;
if (colons == 2) break;
}
}
pos++;
end = pos;
}
try {
// Hours
end = text.Find(_T(':'));
th = StringToInt(text,0,end);
if (colons == 2) {
while (text[end++] != _T(':'));
th = StringToInt(text,pos,end);
pos = end;
}
// Minutes
pos = end+1;
while (text[++end] != _T(':'));
tm = StringToInt(text,pos,end);
if (colons >= 1) {
while (text[end++] != _T(':'));
tm = StringToInt(text,pos,end);
pos = end;
}
// Miliseconds (includes seconds)
pos = end+1;
end = text.Length();
tms = StringToFix(text,3,pos,end);
}
@ -220,34 +242,6 @@ wxString AssTime::GetSRTFormated () {
}
/////////////////////////////////////////////////
// Reads value from a text control and update it
void AssTime::UpdateFromTextCtrl(wxTextCtrl *ctrl) {
long start,end;
wxString text = ctrl->GetValue();
ctrl->GetSelection(&start,&end);
if (start == end) {
wxString nextChar = text.Mid(start,1);
if (nextChar == _T(":") || nextChar == _T(".")) {
wxString temp = text;
text = temp.Left(start-1);
text += nextChar;
text += temp.Mid(start-1,1);
text += temp.Mid(start+2);
start++;
end++;
}
else if (nextChar.IsEmpty()) text.Remove(start-1,1);
else text.Remove(start,1);
}
// Update time
ParseASS(text);
ctrl->SetValue(GetASSFormated());
ctrl->SetSelection(start,end);
}
//////////////////////
// AssTime comparison
bool operator < (AssTime &t1, AssTime &t2) {

View File

@ -65,7 +65,6 @@ public:
void ParseSRT(const wxString text); // Sets value to text-form time, in SRT format
wxString GetASSFormated(bool ms=false); // Returns the ASS representation of time
wxString GetSRTFormated(); // Returns the SRT representation of time
void UpdateFromTextCtrl(wxTextCtrl *ctrl); // Reads value from text control and updates both
};
// Comparison operators

View File

@ -41,6 +41,14 @@
#include "video_context.h"
///////
// IDs
enum {
TEXT_JUMP_TIME = 1100,
TEXT_JUMP_FRAME
};
///////////////
// Constructor
DialogJumpTo::DialogJumpTo (wxWindow *parent)
@ -55,9 +63,7 @@ DialogJumpTo::DialogJumpTo (wxWindow *parent)
wxStaticText *LabelFrame = new wxStaticText(this,-1,_("Frame: "),wxDefaultPosition,wxSize(60,20));
wxStaticText *LabelTime = new wxStaticText(this,-1,_("Time: "),wxDefaultPosition,wxSize(60,20));
JumpFrame = new wxTextCtrl(this,TEXT_JUMP_FRAME,wxString::Format(_T("%i"),jumpframe),wxDefaultPosition,wxSize(60,20));
JumpTime = new wxTextCtrl(this,TEXT_JUMP_TIME,jumptime.GetASSFormated(),wxDefaultPosition,wxSize(60,20));
JumpFrame->SetEventHandler(new DialogJumpToEvent(this));
JumpTime->SetEventHandler(new DialogJumpToEvent(this));
JumpTime = new TimeEdit(this,TEXT_JUMP_TIME,jumptime.GetASSFormated(),wxDefaultPosition,wxSize(60,20));
wxSizer *FrameSizer = new wxBoxSizer(wxHORIZONTAL);
wxSizer *TimeSizer = new wxBoxSizer(wxHORIZONTAL);
FrameSizer->Add(LabelFrame,0,wxALIGN_CENTER_VERTICAL,0);
@ -71,9 +77,6 @@ DialogJumpTo::DialogJumpTo (wxWindow *parent)
// Buttons
wxButton *CancelButton = new wxButton(this,wxID_CANCEL);
wxButton *OKButton = new wxButton(this,wxID_OK);
CancelButton->SetEventHandler(new DialogJumpToEvent(this));
OKButton->SetEventHandler(new DialogJumpToEvent(this));
OKButton->SetDefault();
wxSizer *ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
ButtonSizer->Add(OKButton,1,wxRIGHT,5);
ButtonSizer->Add(CancelButton,0,0,0);
@ -91,29 +94,21 @@ DialogJumpTo::DialogJumpTo (wxWindow *parent)
}
/////////////////
// Event handler
// Constructor
DialogJumpToEvent::DialogJumpToEvent (DialogJumpTo *ctrl) {
control = ctrl;
}
// Table
BEGIN_EVENT_TABLE(DialogJumpToEvent, wxEvtHandler)
EVT_KEY_DOWN(DialogJumpToEvent::OnKey)
EVT_BUTTON(wxID_CANCEL,DialogJumpToEvent::OnClose)
EVT_BUTTON(wxID_OK,DialogJumpToEvent::OnOK)
EVT_TEXT(TEXT_JUMP_TIME, DialogJumpToEvent::OnEditTime)
EVT_TEXT(TEXT_JUMP_FRAME, DialogJumpToEvent::OnEditFrame)
///////////////
// Event table
BEGIN_EVENT_TABLE(DialogJumpTo, wxDialog)
EVT_KEY_DOWN(DialogJumpTo::OnKey)
EVT_BUTTON(wxID_CANCEL,DialogJumpTo::OnClose)
EVT_BUTTON(wxID_OK,DialogJumpTo::OnOK)
EVT_TEXT(TEXT_JUMP_TIME, DialogJumpTo::OnEditTime)
EVT_TEXT(TEXT_JUMP_FRAME, DialogJumpTo::OnEditFrame)
END_EVENT_TABLE()
// Redirects
void DialogJumpToEvent::OnKey (wxKeyEvent &event) { control->OnKey(event); }
void DialogJumpToEvent::OnClose (wxCommandEvent &event) { control->OnClose(false); }
void DialogJumpToEvent::OnOK (wxCommandEvent &event) { control->OnClose(true); }
void DialogJumpToEvent::OnEditTime (wxCommandEvent &event) { control->OnEditTime(event); }
void DialogJumpToEvent::OnEditFrame (wxCommandEvent &event) { control->OnEditFrame(event); }
/////////
// Close
void DialogJumpTo::OnClose (wxCommandEvent &event) { OnClose(false); }
void DialogJumpTo::OnOK (wxCommandEvent &event) { OnClose(true); }
//////////////////
@ -142,10 +137,9 @@ void DialogJumpTo::OnClose(bool ok) {
void DialogJumpTo::OnEditTime (wxCommandEvent &event) {
if (ready) {
ready = false;
jumptime.UpdateFromTextCtrl(JumpTime);
// Update frame
long newframe = VFR_Output.GetFrameAtTime(jumptime.GetMS());
long newframe = VFR_Output.GetFrameAtTime(JumpTime->time.GetMS());
if (jumpframe != newframe) {
jumpframe = newframe;
JumpFrame->SetValue(wxString::Format(_T("%i"),jumpframe));

View File

@ -42,6 +42,7 @@
// Headers
#include <wx/wxprec.h>
#include "ass_time.h"
#include "timeedit_ctrl.h"
/////////
@ -52,43 +53,21 @@ private:
long jumpframe;
AssTime jumptime;
wxTextCtrl *JumpTime;
TimeEdit *JumpTime;
wxTextCtrl *JumpFrame;
public:
DialogJumpTo (wxWindow *parent);
void OnKey(wxKeyEvent &event);
void OnClose(bool ok);
void OnEditTime(wxCommandEvent &event);
void OnEditFrame(wxCommandEvent &event);
};
/////////////////
// Event handler
class DialogJumpToEvent : public wxEvtHandler {
private:
DialogJumpTo *control;
void OnKey(wxKeyEvent &event);
void OnClose(wxCommandEvent &event);
void OnOK(wxCommandEvent &event);
void OnEditTime(wxCommandEvent &event);
void OnEditFrame(wxCommandEvent &event);
void OnClose(bool ok);
public:
DialogJumpToEvent(DialogJumpTo *control);
DialogJumpTo (wxWindow *parent);
DECLARE_EVENT_TABLE()
};
///////
// IDs
enum {
TEXT_JUMP_TIME = 1100,
TEXT_JUMP_FRAME
};
#endif

View File

@ -212,8 +212,8 @@ DialogOptions::DialogOptions(wxWindow *parent)
wxSizer *editSizer5 = new wxBoxSizer(wxHORIZONTAL);
// First static box
wxString labels1[3] = { _("Enable call tips"), _("Enable syntax highlighting"), _("Link commiting of times") };
wxString options1[3] = { _T("Call Tips Enabled"), _T("Syntax Highlight Enabled"), _T("Link Time Boxes Commit") };
wxString labels1[4] = { _("Enable call tips"), _("Enable syntax highlighting"), _("Link commiting of times"), _("Overwrite-Insertion in time boxes") };
wxString options1[4] = { _T("Call Tips Enabled"), _T("Syntax Highlight Enabled"), _T("Link Time Boxes Commit"), _T("Insert Mode on Time Boxes") };
editSizer6->Add(new wxStaticText(editPage,-1,_("Path to dictionary files:")),0,wxALIGN_CENTER_VERTICAL|wxRIGHT,5);
wxTextCtrl *edit = new wxTextCtrl(editPage,-1,_T(""));
Bind(edit,_T("Dictionaries path"));
@ -221,7 +221,7 @@ DialogOptions::DialogOptions(wxWindow *parent)
browse = new BrowseButton(editPage,-1,_T(""),BROWSE_FOLDER);
browse->Bind(edit);
editSizer6->Add(browse,0,wxEXPAND);
for (int i=0;i<3;i++) {
for (int i=0;i<4;i++) {
wxCheckBox *control = new wxCheckBox(editPage,-1,labels1[i]);
Bind(control,options1[i]);
editSizer2->Add(control,1,wxEXPAND,0);

View File

@ -110,6 +110,11 @@ void OptionsManager::LoadDefaults(bool onlyDefaults) {
SetText(_T("Dictionaries path"),_T("dictionaries")); // don't these require restart?
SetText(_T("Spell Checker"),_T("hunspell"));
SetBool(_T("Link time boxes commit"),true);
#ifdef WIN32
SetBool(_T("Insert mode on time boxes"),true);
#else
SetBool(_T("Insert mode on time boxes"),false);
#endif
SetModificationType(MOD_EDIT_BOX);
SetBool(_T("Call tips enabled"),true);
SetBool(_T("Syntax highlight enabled"),true);

View File

@ -86,21 +86,21 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren
ActorBox = new wxComboBox(this,ACTOR_COMBOBOX,_T(""),wxDefaultPosition,wxSize(110,25),styles,wxCB_DROPDOWN | wxTE_PROCESS_ENTER);
ActorBox->SetToolTip(_("Actor name for this speech. This is only for reference, and is mainly useless."));
ActorBox->PushEventHandler(new IdleFieldHandler(ActorBox,_("Actor")));
Effect = new HiliModTextCtrl(this,EFFECT_BOX,_T(""),wxDefaultPosition,wxSize(120,20),wxTE_PROCESS_ENTER);
Effect = new HiliModTextCtrl(this,EFFECT_BOX,_T(""),wxDefaultPosition,wxSize(80,20),wxTE_PROCESS_ENTER);
Effect->SetToolTip(_("Effect for this line. This can be used to store extra information for karaoke scripts, or for the effects supported by the renderer."));
Effect->PushEventHandler(new IdleFieldHandler(Effect,_("Effect")));
// Middle controls
Layer = new wxSpinCtrl(this,LAYER_BOX,_T(""),wxDefaultPosition,wxSize(50,20),wxSP_ARROW_KEYS,0,0x7FFFFFFF,0);
Layer->SetToolTip(_("Layer number"));
StartTime = new TimeEdit(this,STARTTIME_BOX,_T(""),wxDefaultPosition,wxSize(75,20),wxTE_PROCESS_ENTER,NumValidator());
StartTime = new TimeEdit(this,STARTTIME_BOX,_T(""),wxDefaultPosition,wxSize(75,20),wxTE_PROCESS_ENTER);
StartTime->SetToolTip(_("Start time"));
StartTime->showModified = true;
EndTime = new TimeEdit(this,ENDTIME_BOX,_T(""),wxDefaultPosition,wxSize(75,20),wxTE_PROCESS_ENTER,NumValidator());
EndTime = new TimeEdit(this,ENDTIME_BOX,_T(""),wxDefaultPosition,wxSize(75,20),wxTE_PROCESS_ENTER);
EndTime->SetToolTip(_("End time"));
EndTime->isEnd = true;
EndTime->showModified = true;
Duration = new TimeEdit(this,DURATION_BOX,_T(""),wxDefaultPosition,wxSize(75,20),wxTE_PROCESS_ENTER,NumValidator());
Duration = new TimeEdit(this,DURATION_BOX,_T(""),wxDefaultPosition,wxSize(75,20),wxTE_PROCESS_ENTER);
Duration->SetToolTip(_("Line duration"));
Duration->showModified = true;
MarginL = new HiliModTextCtrl(this,MARGINL_BOX,_T(""),wxDefaultPosition,wxSize(40,20),wxTE_CENTRE | wxTE_PROCESS_ENTER,NumValidator());
@ -141,9 +141,9 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren
TopSizer = new wxBoxSizer(wxHORIZONTAL);
//TopSizer->Add(new FloatSpinCtrl(this,-1,wxDefaultPosition,wxSize(40,20),0,-20.0,50.0,0.0,0.5));
TopSizer->Add(CommentBox,0,wxRIGHT | wxALIGN_CENTER,5);
TopSizer->Add(StyleBox,1,wxRIGHT,5);
TopSizer->Add(ActorBox,1,wxRIGHT,5);
TopSizer->Add(Effect,1,0,0);
TopSizer->Add(StyleBox,2,wxRIGHT,5);
TopSizer->Add(ActorBox,2,wxRIGHT,5);
TopSizer->Add(Effect,3,0,0);
// Middle sizer
splitLineMode = true;

View File

@ -48,14 +48,34 @@
TimeEdit::TimeEdit(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name) :
wxTextCtrl(parent,id,value,pos,size,wxTE_CENTRE | style,validator,name)
{
// Set validator
wxTextValidator val(wxFILTER_INCLUDE_CHAR_LIST);
wxArrayString includes;
includes.Add(_T("0"));
includes.Add(_T("1"));
includes.Add(_T("2"));
includes.Add(_T("3"));
includes.Add(_T("4"));
includes.Add(_T("5"));
includes.Add(_T("6"));
includes.Add(_T("7"));
includes.Add(_T("8"));
includes.Add(_T("9"));
includes.Add(_T("."));
includes.Add(_T(":"));
val.SetIncludes(includes);
SetValidator(val);
// Other stuff
SetValue(time.GetASSFormated());
ready = true;
byFrame = false;
isEnd = false;
modified = false;
showModified = false;
time.UpdateFromTextCtrl(this);
UpdateTime();
Connect(wxEVT_COMMAND_TEXT_UPDATED,wxCommandEventHandler(TimeEdit::OnModified));
Connect(wxEVT_KILL_FOCUS,wxFocusEventHandler(TimeEdit::OnKillFocus));
}
@ -72,9 +92,9 @@ END_EVENT_TABLE()
//////////////////
// Modified event
void TimeEdit::OnModified(wxCommandEvent &event) {
event.Skip();
if (!ready) return;
Modified();
event.Skip();
}
@ -87,7 +107,7 @@ void TimeEdit::Modified() {
// Update
if (byFrame) Update();
else time.UpdateFromTextCtrl(this);
else UpdateTime();
// Colour
if (showModified && !modified) {
@ -144,16 +164,128 @@ void TimeEdit::UpdateText() {
}
//////////
// Update
void TimeEdit::Update() {
// Update frame
if (byFrame) {
long temp;
GetValue().ToLong(&temp);
time.SetMS(VFR_Output.GetTimeAtFrame(temp,!isEnd));
}
// Update time if not on insertion mode
else if (!Options.AsBool(_T("Insert Mode on Time Boxes"))) {
UpdateTime();
SetValue(time.GetASSFormated());
}
// Update modified status
if (modified && showModified) {
SetBackgroundColour(wxNullColour);
Refresh();
}
modified = false;
}
/////////////////////////////////////////////////
// Reads value from a text control and update it
void TimeEdit::UpdateTime() {
bool insertion = Options.AsBool(_T("Insert Mode on Time Boxes"));
wxString text = GetValue();
long start=0,end=0;
if (insertion) {
GetSelection(&start,&end);
if (start == end) {
wxString nextChar = text.Mid(start,1);
if (nextChar == _T(":") || nextChar == _T(".")) {
wxString temp = text;
text = temp.Left(start-1);
text += nextChar;
text += temp.Mid(start-1,1);
text += temp.Mid(start+2);
start++;
end++;
}
else if (nextChar.IsEmpty()) text.Remove(start-1,1);
else text.Remove(start,1);
}
}
// Update time
time.ParseASS(text);
if (insertion) {
SetValue(time.GetASSFormated());
SetSelection(start,end);
}
}
///////////////
// Key pressed
void TimeEdit::OnKeyDown(wxKeyEvent &event) {
// Get key ID
int key = event.GetKeyCode();
bool insertMode = Options.AsBool(_T("Insert Mode on Time Boxes"));
Refresh();
// Check if it's an acceptable key
if (!event.ControlDown()) {
if (byFrame || !insertMode || (key != WXK_BACK && key != WXK_DELETE)) {
// Reset selection first, if necessary
if (!byFrame && insertMode) {
long from=0,to=0;
GetSelection(&from,&to);
if (to != from) SetSelection(from,from);
}
// Allow it through
event.Skip();
}
}
else {
// Copy
if (key == 'C' || key == 'X') {
CopyTime();
}
// Paste
if (key == 'V') {
PasteTime();
}
}
}
//////////////
// Focus lost
void TimeEdit::OnKillFocus(wxFocusEvent &event) {
if (!byFrame && !Options.AsBool(_T("Insert Mode on Time Boxes"))) {
if (time.GetASSFormated() != GetValue()) {
UpdateTime();
SetValue(time.GetASSFormated());
}
}
event.Skip();
}
///// Mouse/copy/paste events down here /////
///////////////
// Mouse event
void TimeEdit::OnMouseEvent(wxMouseEvent &event) {
// Right click context menu
if (event.RightUp()) {
wxMenu menu;
menu.Append(Time_Edit_Copy,_T("&Copy"));
menu.Append(Time_Edit_Paste,_T("&Paste"));
PopupMenu(&menu);
return;
if (!byFrame && Options.AsBool(_T("Insert Mode on Time Boxes"))) {
wxMenu menu;
menu.Append(Time_Edit_Copy,_T("&Copy"));
menu.Append(Time_Edit_Paste,_T("&Paste"));
PopupMenu(&menu);
return;
}
}
// Allow other events through
@ -180,60 +312,6 @@ void TimeEdit::OnPaste(wxCommandEvent &event) {
}
//////////
// Update
void TimeEdit::Update() {
// Update frame
if (byFrame) {
long temp;
GetValue().ToLong(&temp);
time.SetMS(VFR_Output.GetTimeAtFrame(temp,!isEnd));
}
// Update modified status
if (modified && showModified) {
SetBackgroundColour(wxNullColour);
Refresh();
}
modified = false;
}
///////////////
// Key pressed
void TimeEdit::OnKeyDown(wxKeyEvent &event) {
// Get key ID
int key = event.GetKeyCode();
// Check if it's an acceptable key
if (!event.ControlDown()) {
if (byFrame || (key != WXK_BACK && key != WXK_DELETE)) {
// Reset selection first, if necessary
if (!byFrame) {
long from=0,to=0;
GetSelection(&from,&to);
if (to != from) SetSelection(from,from);
}
// Allow it through
event.Skip();
}
}
else {
// Copy
if (key == 'C' || key == 'X') {
CopyTime();
}
// Paste
if (key == 'V') {
PasteTime();
}
}
}
/////////////////////
// Copy to clipboard
void TimeEdit::CopyTime() {

View File

@ -55,12 +55,14 @@ private:
void UpdateText();
void CopyTime();
void PasteTime();
void UpdateTime();
void OnModified(wxCommandEvent &event);
void OnMouseEvent(wxMouseEvent &event);
void OnKeyDown(wxKeyEvent &event);
void OnCopy(wxCommandEvent &event);
void OnPaste(wxCommandEvent &event);
void OnKillFocus(wxFocusEvent &event);
public:
AssTime time;