1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-16 08:34:10 +02:00

Merge branch 'master' into HEAD

This commit is contained in:
Paul Licameli 2017-05-09 09:19:55 -04:00
commit a26b79d9fb
8 changed files with 166 additions and 70 deletions

View File

@ -499,7 +499,7 @@ bool EnvelopeEditor::HandleMouseButtonDown(const wxMouseEvent & event, wxRect &
double newVal = ValueOfPixel(clip_y, r.height, upper, dB, dBRange, double newVal = ValueOfPixel(clip_y, r.height, upper, dB, dBRange,
zoomMin, zoomMax); zoomMin, zoomMax);
mEnvelope.SetDragPoint(mEnvelope.InsertOrReplaceRelative(when - mEnvelope.GetOffset(), newVal)); mEnvelope.SetDragPoint(mEnvelope.InsertOrReplaceRelative(when, newVal));
mDirty = true; mDirty = true;
} }

View File

@ -1150,12 +1150,12 @@ void WaveTrack::HandleClear(double t0, double t1,
if (clip->WithinClip(t0)) { if (clip->WithinClip(t0)) {
// start of region within clip // start of region within clip
val = clip->GetEnvelope()->GetValue(t0); val = clip->GetEnvelope()->GetValue(t0);
newClip->GetEnvelope()->InsertOrReplace(t0 - clip->GetOffset() - 1.0 / clip->GetRate(), val); newClip->GetEnvelope()->InsertOrReplace(t0 - 1.0 / clip->GetRate(), val);
} }
if (clip->WithinClip(t1)) if (clip->WithinClip(t1))
{ // end of region within clip { // end of region within clip
val = clip->GetEnvelope()->GetValue(t1); val = clip->GetEnvelope()->GetValue(t1);
newClip->GetEnvelope()->InsertOrReplace(t1 - clip->GetOffset(), val); newClip->GetEnvelope()->InsertOrReplace(t1 , val);
} }
} }
newClip->Clear(t0,t1); newClip->Clear(t0,t1);
@ -1430,6 +1430,10 @@ void WaveTrack::Silence(double t0, double t1)
void WaveTrack::InsertSilence(double t, double len) void WaveTrack::InsertSilence(double t, double len)
// STRONG-GUARANTEE // STRONG-GUARANTEE
{ {
// Nothing to do, if length is zero.
// Fixes Bug 1626
if( len == 0 )
return;
if (len <= 0) if (len <= 0)
THROW_INCONSISTENCY_EXCEPTION; THROW_INCONSISTENCY_EXCEPTION;

View File

@ -981,6 +981,7 @@ wxString CommandManager::GetLabelWithDisabledAccel(const CommandListEntry *entry
{ {
// Dummy accelerator that looks Ok in menus but is non functional. // Dummy accelerator that looks Ok in menus but is non functional.
// Note the space before the key. // Note the space before the key.
#ifdef __WXMSW__
Accel = wxString("\t ") + entry->key; Accel = wxString("\t ") + entry->key;
if( entry->key.StartsWith("Left" )) break; if( entry->key.StartsWith("Left" )) break;
if( entry->key.StartsWith("Right")) break; if( entry->key.StartsWith("Right")) break;
@ -1006,6 +1007,7 @@ wxString CommandManager::GetLabelWithDisabledAccel(const CommandListEntry *entry
if( entry->key.StartsWith("NUMPAD_ENTER" )) break; if( entry->key.StartsWith("NUMPAD_ENTER" )) break;
if( entry->key.StartsWith("Backspace" )) break; if( entry->key.StartsWith("Backspace" )) break;
if( entry->key.StartsWith("Delete" )) break; if( entry->key.StartsWith("Delete" )) break;
#endif
//wxLogDebug("Added Accel:[%s][%s]", entry->label, entry->key ); //wxLogDebug("Added Accel:[%s][%s]", entry->label, entry->key );
// Normal accelerator. // Normal accelerator.
Accel = wxString("\t") + entry->key; Accel = wxString("\t") + entry->key;

View File

@ -1613,8 +1613,8 @@ void EffectEqualization::SaveCurves(const wxString &fileName)
void EffectEqualization::setCurve(int currentCurve) void EffectEqualization::setCurve(int currentCurve)
{ {
// Set current choice // Set current choice
Select(currentCurve);
wxASSERT( currentCurve < (int) mCurves.GetCount() ); wxASSERT( currentCurve < (int) mCurves.GetCount() );
Select(currentCurve);
Envelope *env; Envelope *env;
int numPoints = (int) mCurves[currentCurve].points.GetCount(); int numPoints = (int) mCurves[currentCurve].points.GetCount();
@ -2660,6 +2660,7 @@ void EffectEqualization::OnSliderDBMAX(wxCommandEvent & WXUNUSED(event))
void EffectEqualization::OnCurve(wxCommandEvent & WXUNUSED(event)) void EffectEqualization::OnCurve(wxCommandEvent & WXUNUSED(event))
{ {
// Select NEW curve // Select NEW curve
wxASSERT( mCurve != NULL );
setCurve( mCurve->GetCurrentSelection() ); setCurve( mCurve->GetCurrentSelection() );
if( !mDrawMode ) if( !mDrawMode )
UpdateGraphic(); UpdateGraphic();

View File

@ -155,7 +155,7 @@ void RecordingPrefs::PopulateOrExchange(ShuttleGui & S)
S.StartStatic(_("Options")); S.StartStatic(_("Options"));
{ {
S.TieCheckBox(_("Record appends, instead of recording new track"), S.TieCheckBox(_("Record &appends, instead of recording new track"),
wxT("/GUI/PreferAppendRecord"), wxT("/GUI/PreferAppendRecord"),
true); true);
} }

View File

@ -118,7 +118,7 @@ void TracksPrefs::PopulateOrExchange(ShuttleGui & S)
mViewCodes); mViewCodes);
S.SetSizeHints(mViewChoices); S.SetSizeHints(mViewChoices);
S.TieChoice(_("Display samples:"), S.TieChoice(_("Display &samples:"),
wxT("/GUI/SampleView"), wxT("/GUI/SampleView"),
0, 0,
mSampleDisplayChoice, mSampleDisplayChoice,

View File

@ -66,6 +66,8 @@ enum {
SelectionBarFirstID = 2700, SelectionBarFirstID = 2700,
OnRateID, OnRateID,
OnSnapToID, OnSnapToID,
OnStartRadioID,
OnCenterRadioID,
OnLengthRadioID, OnLengthRadioID,
OnEndRadioID, OnEndRadioID,
OnLeftTimeID, OnLeftTimeID,
@ -76,6 +78,8 @@ BEGIN_EVENT_TABLE(SelectionBar, ToolBar)
EVT_SIZE(SelectionBar::OnSize) EVT_SIZE(SelectionBar::OnSize)
EVT_TEXT(OnLeftTimeID, SelectionBar::OnLeftTime) EVT_TEXT(OnLeftTimeID, SelectionBar::OnLeftTime)
EVT_TEXT(OnRightTimeID, SelectionBar::OnRightTime) EVT_TEXT(OnRightTimeID, SelectionBar::OnRightTime)
EVT_RADIOBUTTON(OnStartRadioID, SelectionBar::OnStartRadio)
EVT_RADIOBUTTON(OnCenterRadioID, SelectionBar::OnCenterRadio)
EVT_RADIOBUTTON(OnLengthRadioID, SelectionBar::OnLengthRadio) EVT_RADIOBUTTON(OnLengthRadioID, SelectionBar::OnLengthRadio)
EVT_RADIOBUTTON(OnEndRadioID, SelectionBar::OnEndRadio) EVT_RADIOBUTTON(OnEndRadioID, SelectionBar::OnEndRadio)
EVT_CHOICE(OnSnapToID, SelectionBar::OnSnapTo) EVT_CHOICE(OnSnapToID, SelectionBar::OnSnapTo)
@ -109,6 +113,39 @@ void SelectionBar::Create(wxWindow * parent)
ToolBar::Create(parent); ToolBar::Create(parent);
} }
// Can't set textcolour of radio buttons.
// so instead if we want to them, we make the text empty and add in a wxStaticText
// and we can set the colour of that.
// Slight regression relative ot Audacity, in that this text is not
// clickable/active. You have to click on the actual button.
// And you can't tab between and hear the labels with voice over.
// So VI users should use blend themes (which is the default).
// Should not be a hardship for them, as themes make little difference
// for them, except Hi-Contrast, which should be used with blend thems
// and a windows theme that is close enough to actually blend.
wxRadioButton * SelectionBar::AddRadioButton( const wxString & Name,
int id, std::unique_ptr<wxBoxSizer>& pSizer, long style )
{
bool bUseNativeRadioButton = theTheme.IsUsingSyestemTextColour();
wxRadioButton * pBtn;
// Safenew because the button is being create dinto this window.
pBtn = safenew wxRadioButton(this, id,bUseNativeRadioButton ? Name : wxT(""),
wxDefaultPosition, wxDefaultSize, style);
pBtn->SetName(Name);
pBtn->SetForegroundColour( theTheme.Colour( clrTrackPanelText ));
pSizer->Add(pBtn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
if( !bUseNativeRadioButton )
{
wxStaticText * pText = safenew wxStaticText(this, -1, Name);
pText->SetForegroundColour( theTheme.Colour( clrTrackPanelText ) );
pSizer->Add(pText, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
}
return pBtn;
}
void SelectionBar::Populate() void SelectionBar::Populate()
{ {
SetBackgroundColour( theTheme.Colour( clrMedium ) ); SetBackgroundColour( theTheme.Colour( clrMedium ) );
@ -156,56 +193,31 @@ void SelectionBar::Populate()
pSnapTo->SetForegroundColour( clrText ); pSnapTo->SetForegroundColour( clrText );
mainSizer->Add( pSnapTo, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5); mainSizer->Add( pSnapTo, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
wxStaticText * pSelStart = safenew wxStaticText(this, -1, _("Selection Start:"));
pSelStart->SetForegroundColour( clrText );
mainSizer->Add( pSelStart,0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
bool showSelectionStart = false;
bool showSelectionLength = false; bool showSelectionLength = false;
gPrefs->Read(wxT("/ShowSelectionLength"), &showSelectionLength); gPrefs->Read(wxT("/ShowSelectionStart"), &showSelectionStart, true);
gPrefs->Read(wxT("/ShowSelectionLength"), &showSelectionLength, false);
{ {
bool bSysTextColour = theTheme.IsUsingSyestemTextColour();
// Can't set textcolour of radio buttons.
// so instead we make the text empty and add in two wxStaticTexts
// and we can set the colour of those.
// Slight regression relative ot Audacity, in that this text is not
// clickable/active. You have to click on the actual button.
// And can't tab between and hear the labels with voice over.
// So VI users should use blend themes (which is the default).
// Should not be a hardship for them, as themes make little difference
// for them, except Hi-Contrast, which should be used with recolouring.
auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL); auto hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
mRightEndButton = safenew wxRadioButton(this, OnEndRadioID, bSysTextColour ? _("End") : wxT("") ,
wxDefaultPosition, wxDefaultSize,
wxRB_GROUP);
mRightEndButton->SetName(_("End"));
mRightEndButton->SetForegroundColour( clrText );
mRightEndButton->SetValue(!showSelectionLength);
hSizer->Add(mRightEndButton,
0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
if( !bSysTextColour )
{
wxStaticText * pEndText = safenew wxStaticText(this, -1, _("End"));
pEndText->SetForegroundColour( clrText );
hSizer->Add(pEndText,
0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
}
mRightLengthButton = safenew wxRadioButton(this, OnLengthRadioID,bSysTextColour ? _("Length") : wxT("") ); wxStaticText * pSelStart = safenew wxStaticText(this, -1, _("Selection:"));
mRightLengthButton->SetName(_("Length")); pSelStart->SetForegroundColour( clrText );
mRightLengthButton->SetForegroundColour( clrText ); hSizer->Add( pSelStart,0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
mRightLengthButton->SetValue(showSelectionLength);
hSizer->Add(mRightLengthButton,
0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5);
if( !bSysTextColour )
{
wxStaticText * pLengthText = safenew wxStaticText(this, -1, _("Length"));
pLengthText->SetForegroundColour( clrText );
hSizer->Add(pLengthText,
0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5);
}
#if defined(__WXMSW__) mSelStartButton = AddRadioButton( _("Start"), OnStartRadioID, hSizer, wxRB_GROUP);
mSelStartButton->SetValue(showSelectionStart);
AddRadioButton( _("Center"), OnCenterRadioID, hSizer, 0)->SetValue(!showSelectionStart);
mainSizer->Add(hSizer.release(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 0);
hSizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
mSelEndButton = AddRadioButton( _("End"), OnEndRadioID, hSizer, wxRB_GROUP);
mSelEndButton->SetValue(!showSelectionLength);
AddRadioButton( _("Length"), OnLengthRadioID, hSizer, 0)->SetValue(showSelectionLength);
#if 0
// was #if defined(__WXMSW__)
// Refer to Microsoft KB article 261192 for an explanation as // Refer to Microsoft KB article 261192 for an explanation as
// to why this is needed. We've only experienced it under Win2k // to why this is needed. We've only experienced it under Win2k
// so it's probably been fixed. But, it doesn't hurt to have this // so it's probably been fixed. But, it doesn't hurt to have this
@ -373,18 +385,44 @@ void SelectionBar::OnSize(wxSizeEvent &evt)
void SelectionBar::ModifySelection(bool done) void SelectionBar::ModifySelection(bool done)
{ {
mStart = mLeftTime->GetValue(); double left = mLeftTime->GetValue();
double right = mRightTime->GetValue(); double right = mRightTime->GetValue();
if (mRightEndButton->GetValue()) { // Four combinations:
if(mStart > right)
mEnd = mStart;
else
mEnd = right;
}
else
mEnd = mStart + right;
const int kStart = 0;
const int kCenter = 1;
const int kEnd = 0;
const int kLength = 2;
int option = (mSelStartButton->GetValue()? kStart:kCenter) + (mSelEndButton->GetValue()? kEnd:kLength);
switch( option ){
case kStart+kEnd:
if( right < left )
right = left;
mStart = wxMin( left, right );
mEnd = wxMax( left, right);
break;
case kCenter+kEnd:
if( right < left )
right = left;
mStart = left - fabs( right-left );
mEnd = left + fabs( right-left);
break;
case kStart+kLength:
if( right < 0 )
right = 0;
mStart = wxMin( left, left+right );
mEnd = wxMax( left, left+right);
break;
case kCenter+kLength:
if( right < 0 )
right = 0;
mStart = left - fabs( right)/2.0;
mEnd = left + fabs( right)/2.0;
break;
}
mListener->AS_ModifySelection(mStart, mEnd, done); mListener->AS_ModifySelection(mStart, mEnd, done);
} }
@ -398,6 +436,24 @@ void SelectionBar::OnRightTime(wxCommandEvent & event)
ModifySelection(event.GetInt() != 0); ModifySelection(event.GetInt() != 0);
} }
void SelectionBar::OnStartRadio(wxCommandEvent & WXUNUSED(event))
{
gPrefs->Write(wxT("/ShowSelectionStart"), true);
gPrefs->Flush();
mLeftTime->SetName(wxString(_("Selection Start")));
ValuesToControls();
}
void SelectionBar::OnCenterRadio(wxCommandEvent & WXUNUSED(event))
{
gPrefs->Write(wxT("/ShowSelectionStart"), false);
gPrefs->Flush();
mLeftTime->SetName(wxString(_("Selection Center")));
ValuesToControls();
}
void SelectionBar::OnLengthRadio(wxCommandEvent & WXUNUSED(event)) void SelectionBar::OnLengthRadio(wxCommandEvent & WXUNUSED(event))
{ {
gPrefs->Write(wxT("/ShowSelectionLength"), true); gPrefs->Write(wxT("/ShowSelectionLength"), true);
@ -410,6 +466,7 @@ void SelectionBar::OnLengthRadio(wxCommandEvent & WXUNUSED(event))
void SelectionBar::OnEndRadio(wxCommandEvent & WXUNUSED(event)) void SelectionBar::OnEndRadio(wxCommandEvent & WXUNUSED(event))
{ {
gPrefs->Write(wxT("/ShowSelectionLength"), false); gPrefs->Write(wxT("/ShowSelectionLength"), false);
gPrefs->Flush();
mRightTime->SetName(wxString(_("Selection End"))); mRightTime->SetName(wxString(_("Selection End")));
ValuesToControls(); ValuesToControls();
@ -439,8 +496,8 @@ void SelectionBar::OnUpdate(wxCommandEvent &evt)
mRightTime = mRightTime =
mAudioTime = NULL; mAudioTime = NULL;
mRightEndButton = mSelStartButton = NULL;
mRightLengthButton = NULL; mSelEndButton = NULL;
mRateBox = NULL; mRateBox = NULL;
mRateText = NULL; mRateText = NULL;
@ -469,20 +526,46 @@ void SelectionBar::OnUpdate(wxCommandEvent &evt)
void SelectionBar::ValuesToControls() void SelectionBar::ValuesToControls()
{ {
mLeftTime->SetValue(mStart); double left;
double right;
if (mRightEndButton->GetValue()) // Start or center?
mRightTime->SetValue(mEnd); if (mSelStartButton->GetValue())
left = mStart;
else else
{ // mRightTime is the length. {
// Be sure to take into account the sub-sample offset. // TODO: Doing rounding calcs here, as in the length case, but
// not sure that is needed.
//left = (mStart+mEnd)/2.0;
auto samples = (sampleCount)floor(mEnd * mRate + 0.5);
samples += (sampleCount)floor(mStart * mRate + 0.5);
auto t = samples.as_double() / mRate;
// An odd thing here is that we could allow the center to be at half a sample.
// If center is at a half sample length must be odd.
// If center is at a sample length must be even.
// Similarly for any selection granularity.
// For now, we don't care, and don't do anything to ensure that.
// The user gets the benefit from having the option of center, even if
// it is slightly peculiar in its interactions with selection granularity.
left = t/2.0;
}
// End or length?
if (mSelEndButton->GetValue())
right = mEnd;
else
{ // Be sure to take into account the sub-sample offset.
// See TimeToLongSamples and LongSamplesToTime but here at the project rate. // See TimeToLongSamples and LongSamplesToTime but here at the project rate.
auto samples = (sampleCount)floor(mEnd * mRate + 0.5); auto samples = (sampleCount)floor(mEnd * mRate + 0.5);
samples -= (sampleCount)floor(mStart * mRate + 0.5); samples -= (sampleCount)floor(mStart * mRate + 0.5);
auto t = samples.as_double() / mRate; auto t = samples.as_double() / mRate;
mRightTime->SetValue(t); right = t;
} }
mLeftTime->SetValue(left);
mRightTime->SetValue(right);
mAudioTime->SetValue(mAudio); mAudioTime->SetValue(mAudio);
} }
@ -502,7 +585,7 @@ double SelectionBar::GetLeftTime()
double SelectionBar::GetRightTime() double SelectionBar::GetRightTime()
{ {
if (mRightEndButton->GetValue()) if (mSelEndButton->GetValue())
return mRightTime->GetValue(); return mRightTime->GetValue();
else { else {
// What would be shown if we were showing the end time // What would be shown if we were showing the end time

View File

@ -52,12 +52,16 @@ class SelectionBar final : public ToolBar {
void RegenerateTooltips() override; void RegenerateTooltips() override;
private: private:
wxRadioButton * AddRadioButton( const wxString & Name, int id,
std::unique_ptr<wxBoxSizer>& pSizer, long style);
void ValuesToControls(); void ValuesToControls();
void OnUpdate(wxCommandEvent &evt); void OnUpdate(wxCommandEvent &evt);
void OnLeftTime(wxCommandEvent &evt); void OnLeftTime(wxCommandEvent &evt);
void OnRightTime(wxCommandEvent &evt); void OnRightTime(wxCommandEvent &evt);
void OnStartRadio(wxCommandEvent &evt);
void OnCenterRadio(wxCommandEvent &evt);
void OnEndRadio(wxCommandEvent &evt); void OnEndRadio(wxCommandEvent &evt);
void OnLengthRadio(wxCommandEvent &evt); void OnLengthRadio(wxCommandEvent &evt);
@ -79,10 +83,12 @@ class SelectionBar final : public ToolBar {
double mStart, mEnd, mAudio; double mStart, mEnd, mAudio;
wxString mField[10]; wxString mField[10];
bool mbUseNativeRadioButton;
NumericTextCtrl *mLeftTime; NumericTextCtrl *mLeftTime;
NumericTextCtrl *mRightTime; NumericTextCtrl *mRightTime;
wxRadioButton *mRightEndButton; wxRadioButton *mSelStartButton; // for start/center
wxRadioButton *mRightLengthButton; wxRadioButton *mSelEndButton; // for end/length
NumericTextCtrl *mAudioTime; NumericTextCtrl *mAudioTime;
wxComboBox *mRateBox; wxComboBox *mRateBox;