stevethefiddle wrote:
Could you tell us more about how you did that, or perhaps a patch?
A patch might rapidly become stale and almost certainly never be applied. The developers of Audacity are very reluctant to add these kinds of features at this time, because of feature and preferences creep. If the patch were not applied to the SVN head, anyone who wish to use it would need to modify the patch frequently as the SVN HEAD changed, I will attach a patch to this-- .patch files not allowed -- attached file trd.patch.txt needs a name change to trd.patch.
Here's a description of the current situation and enough information so that anyone who is compiling their own version of Audacity may make this change for themselves (all line numbers are approximate).
As we can see, the Selection Toolbar already recalls its state by saving the information in Audacity's preferences file:
(a snippet from the preference file with default setting)
Code: Select all
NewPrefsInitialized=1
Version=1.3.13-alpha-Jul 19 2010
[...]
SelectionFormat=hh:mm:ss
(a snippet after changing that setting)
Code: Select all
NewPrefsInitialized=1
Version=1.3.13-alpha-Jul 19 2010
[...]
SelectionFormat=CDDA frames (75 fps)
Here is how the Selection Toolbar does this
srctoolbarsSelectionBar.cpp line number 101 (read in from preferences):
Code: Select all
void SelectionBar::Populate()
{
[...]
TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, mRate);
wxString formatName;
gPrefs->Read(wxT("/SelectionFormat"), &formatName);
wxString format = ttc->GetBuiltinFormat(formatName);
delete ttc;
srctoolbarsSelectionBar.cpp line number 344 (write to preferences):
Code: Select all
void SelectionBar::OnUpdate(wxCommandEvent &evt)
{
[...]
TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, mRate);
wxString formatName(ttc->GetBuiltinName(index));
gPrefs->Write(wxT("/SelectionFormat"), formatName);
delete ttc;
Now we know
how to do it. The next step is to decide
where to do it. My solution might be overkill for some but what I did was search the entire Audacity project for "new TimeTextCtrl". This gives me most if not all of the occasions where this kind of control is used:
Code: Select all
Find all "new TimeTextCtrl", Regular expressions, Subfolders, Find Results 1, "Entire Solution", "*.c; *.cpp"
D:audioAudacitySVNsrcSnap.cpp(47): ttc = new TimeTextCtrl(p, wxID_ANY, wxT(""), 0.0, p->GetRate());
D:audioAudacitySVNsrcTimerRecordDialog.cpp(337): m_pTimeTextCtrl_Start = new TimeTextCtrl(this, ID_TIMETEXT_START, strFormat);
D:audioAudacitySVNsrcTimerRecordDialog.cpp(356): m_pTimeTextCtrl_End = new TimeTextCtrl(this, ID_TIMETEXT_END, strFormat);
D:audioAudacitySVNsrcTimerRecordDialog.cpp(367): m_pTimeTextCtrl_Duration = new TimeTextCtrl(this, ID_TIMETEXT_DURATION, strFormat1);
D:audioAudacitySVNsrctoolbarsSelectionBar.cpp(113): TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, mRate);
D:audioAudacitySVNsrctoolbarsSelectionBar.cpp(244): mLeftTime = new TimeTextCtrl(this, OnLeftTimeID, wxT(""), 0.0, mRate);
D:audioAudacitySVNsrctoolbarsSelectionBar.cpp(250): mRightTime = new TimeTextCtrl(this, OnRightTimeID, format, 0.0, mRate);
D:audioAudacitySVNsrctoolbarsSelectionBar.cpp(262): mAudioTime = new TimeTextCtrl(this, -1, format, 0.0, mRate);
D:audioAudacitySVNsrctoolbarsSelectionBar.cpp(357): TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, mRate);
D:audioAudacitySVNsrcwidgetsGrid.cpp(47): m_control = new TimeTextCtrl(parent,
D:audioAudacitySVNsrcwidgetsTimeTextCtrl.cpp(417): SetAccessible(new TimeTextCtrlAx(this));
Matching lines: 11 Matching files: 5 Total files searched: 873
Since we are trying to change the Timer Record Dialog, let's look at that code...
srcTimerRecordDialog.cpp line number 320:
Code: Select all
void TimerRecordDialog::PopulateOrExchange(ShuttleGui& S)
{
[...]
wxString strFormat = wxT("099 h 060 m 060 s");
[...]
m_pTimeTextCtrl_Start = new TimeTextCtrl(this, ID_TIMETEXT_START, strFormat);
As we can see the Timer Record Dialog uses a hardcoded format string where the Selection Toolbar reads the string in from preferences (note -- if the entry does not exist in preferences an appropriate default is used by the call to GetBuiltinFormat ()). What we want to do is read and write a preference for the Timer Record Dialog TimeTextCtrl just like we do for the Selection Toolbar (this involves adding an Event and an Update function plus doing the actual code changes).
srcTimerRecordDialog.h line number 47 add function declaration:
Code: Select all
void OnUpdate(wxCommandEvent &evt);
srcTimerRecordDialog.cpp at end-of-file add function definition:
Code: Select all
void TimerRecordDialog::OnUpdate(wxCommandEvent &evt)
{
int index = evt.GetInt();
evt.Skip(true);
/* we don't actually need a TimeTextCtrl, but need it's
* translations which are done at runtime */
TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, 0.0);
wxString formatName(ttc->GetBuiltinName(index));
gPrefs->Write(wxT("/TimerRecordDialogFormat"), formatName);
delete ttc;
}
srcTimerRecordDialog.cpp at line number 67 add the event to the table:
Code: Select all
EVT_COMMAND(wxID_ANY, EVT_TIMETEXTCTRL_UPDATED, TimerRecordDialog::OnUpdate)
srcTimerRecordDialog.cpp at line number 320 this is where the real changes are made:
Code: Select all
void TimerRecordDialog::PopulateOrExchange(ShuttleGui& S)
{
S.SetBorder(5);
S.StartVerticalLay(true);
{
/* we don't actually need a control yet, but we want to use it's methods
* to do some look-ups, so we'll have to create one. We can't make the
* look-ups static because they depend on translations which are done at
* runtime */
TimeTextCtrl *ttc = new TimeTextCtrl(this, wxID_ANY, wxT(""), 0.0, 0.0);
wxString formatName;
gPrefs->Read(wxT("/TimerRecordDialogFormat"), &formatName);
wxString format = ttc->GetBuiltinFormat(formatName);
delete ttc;
S.StartStatic(_("Start Date and Time"), true);
{
m_pDatePickerCtrl_Start =
new wxDatePickerCtrl(this, // wxWindow *parent,
ID_DATEPICKER_START, // wxWindowID id,
m_DateTime_Start); // const wxDateTime& dt = wxDefaultDateTime,
// const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDP_DEFAULT | wxDP_SHOWCENTURY, const wxValidator& validator = wxDefaultValidator, const wxString& name = "datectrl")
m_pDatePickerCtrl_Start->SetName(_("Start Date"));
m_pDatePickerCtrl_Start->SetRange(wxDateTime::Today(), wxInvalidDateTime); // No backdating.
S.AddWindow(m_pDatePickerCtrl_Start);
m_pTimeTextCtrl_Start = new TimeTextCtrl(this, ID_TIMETEXT_START, format);
m_pTimeTextCtrl_Start->EnableMenu(true);
m_pTimeTextCtrl_Start->SetName(_("Start Time"));
m_pTimeTextCtrl_Start->SetTimeValue(wxDateTime_to_AudacityTime(m_DateTime_Start));
S.AddWindow(m_pTimeTextCtrl_Start);
}
S.EndStatic();
S.StartStatic(_("End Date and Time"), true);
{
m_pDatePickerCtrl_End =
new wxDatePickerCtrl(this, // wxWindow *parent,
ID_DATEPICKER_END, // wxWindowID id,
m_DateTime_End); // const wxDateTime& dt = wxDefaultDateTime,
// const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDP_DEFAULT | wxDP_SHOWCENTURY, const wxValidator& validator = wxDefaultValidator, const wxString& name = "datectrl")
m_pDatePickerCtrl_End->SetRange(m_DateTime_Start, wxInvalidDateTime); // No backdating.
m_pDatePickerCtrl_End->SetName(_("End Date"));
S.AddWindow(m_pDatePickerCtrl_End);
m_pTimeTextCtrl_End = new TimeTextCtrl(this, ID_TIMETEXT_END, format);
m_pTimeTextCtrl_Start->EnableMenu(true);
m_pTimeTextCtrl_End->SetName(_("End Time"));
m_pTimeTextCtrl_End->SetTimeValue(wxDateTime_to_AudacityTime(m_DateTime_End));
S.AddWindow(m_pTimeTextCtrl_End);
}
S.EndStatic();
S.StartStatic(_("Duration"), true);
{
m_pTimeTextCtrl_Duration = new TimeTextCtrl(this, ID_TIMETEXT_DURATION, format);
m_pTimeTextCtrl_Duration->SetName(_("Duration"));
m_pTimeTextCtrl_Duration->SetTimeValue(
Internat::CompatibleToDouble(m_TimeSpan_Duration.GetSeconds().ToString()));
S.AddWindow(m_pTimeTextCtrl_Duration);
}
S.EndStatic();
}
S.EndVerticalLay();
S.AddStandardButtons();
Layout();
Fit();
SetMinSize(GetSize());
Center();
}
This has some GUI defects. The window is hardcoded to a fixed width so the longer styles of time control will not fit--again easy to fix (and does not affect me) but the developers are resistant to that kind of change for some reason. Also, when one changes a single control the other controls do not change until the program is closed and re-opened--one may change them all manually so no big deal.
Error checking is also left out--it may well be fatal to set the "start time" in NTSC Frames, Samples or other non-time based "times"!
Code: Select all
NewPrefsInitialized=1
Version=1.3.13-alpha-Jul 21 2010
PrefsVersion=1.1.1r1
[...]
SelectionFormat=CDDA frames (75 fps)
[...]
TimerRecordDialogFormat=samples