diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 8fe7ab573..dd1e9abc2 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -347,6 +347,9 @@ enum { OnZoomInVerticalID, OnZoomOutVerticalID, OnZoomFitVerticalID, + + IDFormatMenu, + IDRateMenu, }; BEGIN_EVENT_TABLE(TrackPanel, wxWindow) @@ -552,7 +555,8 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id, mAdjustLeftSelectionCursor = new wxCursor(wxCURSOR_POINT_LEFT); mAdjustRightSelectionCursor = new wxCursor(wxCURSOR_POINT_RIGHT); - mWaveTrackMenu = NULL; + mMonoTrackMenu = NULL; + mStereoTrackMenu = NULL; mNoteTrackMenu = NULL; mLabelTrackMenu = NULL; mTimeTrackMenu = NULL; @@ -726,28 +730,22 @@ void TrackPanel::BuildMenus(void) mFormatMenu->AppendRadioItem(On24BitID, GetSampleFormatStr(int24Sample)); mFormatMenu->AppendRadioItem(OnFloatID, GetSampleFormatStr(floatSample)); - /* build the pop-down menu used on wave (sampled audio) tracks */ - mWaveTrackMenu = new wxMenu(); - BuildCommonDropMenuItems(mWaveTrackMenu); // does name, up/down etc - mWaveTrackMenu->AppendRadioItem(OnWaveformID, _("&Waveform")); - mWaveTrackMenu->AppendRadioItem(OnSpectrumID, _("&Spectrum")); - mWaveTrackMenu->Append(OnViewSettingsID, _("&View Settings...")); - mWaveTrackMenu->AppendSeparator(); + /* build the pop-down menus used on wave (sampled audio) tracks */ + mMonoTrackMenu = new wxMenu(); + BuildCommonDropMenuItems(mMonoTrackMenu); // does name, up/down etc + BuildWaveTrackMenuItems(mMonoTrackMenu, true); + mMonoTrackMenu->Append(IDFormatMenu, _("&Format"), mFormatMenu); + mMonoTrackMenu->AppendSeparator(); + mMonoTrackMenu->Append(IDRateMenu, _("&Rate"), mRateMenu); - mWaveTrackMenu->AppendRadioItem(OnChannelMonoID, _("&Mono")); - mWaveTrackMenu->AppendRadioItem(OnChannelLeftID, _("&Left Channel")); - mWaveTrackMenu->AppendRadioItem(OnChannelRightID, _("&Right Channel")); - mWaveTrackMenu->Append(OnMergeStereoID, _("Ma&ke Stereo Track")); - mWaveTrackMenu->Append(OnSwapChannelsID, _("Swap Stereo &Channels")); - mWaveTrackMenu->Append(OnSplitStereoID, _("Spl&it Stereo Track")); - mWaveTrackMenu->Append(OnSplitStereoMonoID, _("Split Stereo to Mo&no")); - mWaveTrackMenu->AppendSeparator(); - - mWaveTrackMenu->Append(0, _("&Format"), mFormatMenu); - - mWaveTrackMenu->AppendSeparator(); - - mWaveTrackMenu->Append(0, _("&Rate"), mRateMenu); + mStereoTrackMenu = new wxMenu(); + BuildCommonDropMenuItems(mStereoTrackMenu); // does name, up/down etc + BuildWaveTrackMenuItems(mStereoTrackMenu, false); + // Following lines share a sub-menu! We must be careful when destroying + // these menus later, to avoid double deletion of the sub-menus. + mStereoTrackMenu->Append(0, _("&Format"), mFormatMenu); + mStereoTrackMenu->AppendSeparator(); + mStereoTrackMenu->Append(0, _("&Rate"), mRateMenu); /* build the pop-down menu used on note (MIDI) tracks */ mNoteTrackMenu = new wxMenu(); @@ -792,6 +790,27 @@ void TrackPanel::BuildCommonDropMenuItems(wxMenu * menu) } +void TrackPanel::BuildWaveTrackMenuItems(wxMenu * menu, bool mono) +{ + menu->AppendRadioItem(OnWaveformID, _("&Waveform")); + menu->AppendRadioItem(OnSpectrumID, _("&Spectrum")); + menu->Append(OnViewSettingsID, _("&View Settings...")); + menu->AppendSeparator(); + + if (mono) { + menu->AppendRadioItem(OnChannelMonoID, _("&Mono")); + menu->AppendRadioItem(OnChannelLeftID, _("&Left Channel")); + menu->AppendRadioItem(OnChannelRightID, _("R&ight Channel")); + menu->Append(OnMergeStereoID, _("Ma&ke Stereo Track")); + } + else { + menu->Append(OnSwapChannelsID, _("Swap Stereo &Channels")); + menu->Append(OnSplitStereoID, _("Spl&it Stereo Track")); + menu->Append(OnSplitStereoMonoID, _("Split Stereo to &Mono")); + } + menu->AppendSeparator(); +} + // static void TrackPanel::BuildVRulerMenuItems (wxMenu * menu, int firstId, const wxArrayString &names) @@ -809,9 +828,27 @@ void TrackPanel::DeleteMenus(void) { // Note that the submenus (mRateMenu, ...) // are deleted by their parent - if (mWaveTrackMenu) { - delete mWaveTrackMenu; - mWaveTrackMenu = NULL; + if (mMonoTrackMenu) { + // Avoid double deletion of the sub-menus shared with the stereo menu + wxMenuItem *pItem; + + pItem = mMonoTrackMenu->Remove(IDFormatMenu); + wxASSERT(pItem->GetSubMenu() == mFormatMenu); + pItem->SetSubMenu(NULL); + delete pItem; + + pItem = mMonoTrackMenu->Remove(IDRateMenu); + wxASSERT(pItem->GetSubMenu() == mRateMenu); + pItem->SetSubMenu(NULL); + delete pItem; + + delete mMonoTrackMenu; + mMonoTrackMenu = NULL; + } + + if (mStereoTrackMenu) { + delete mStereoTrackMenu; + mStereoTrackMenu = NULL; } if (mNoteTrackMenu) { @@ -8342,33 +8379,29 @@ void TrackPanel::OnTrackMenu(Track *t) } if (t->GetKind() == Track::Wave) { - theMenu = mWaveTrackMenu; - if (next && !t->GetLinked() && !next->GetLinked() + const bool isMono = !t->GetLinked(); + theMenu = isMono? mMonoTrackMenu : mStereoTrackMenu; + if (next && isMono && !next->GetLinked() && t->GetKind() == Track::Wave && next->GetKind() == Track::Wave) canMakeStereo = true; - theMenu->Enable(OnSwapChannelsID, t->GetLinked()); - theMenu->Enable(OnMergeStereoID, canMakeStereo); - theMenu->Enable(OnSplitStereoID, t->GetLinked()); - theMenu->Enable(OnSplitStereoMonoID, t->GetLinked()); + if (isMono) { + theMenu->Enable(OnMergeStereoID, canMakeStereo); - // We only need to set check marks. Clearing checks causes problems on Linux (bug 851) - switch (t->GetChannel()) { - case Track::LeftChannel: - theMenu->Check(OnChannelLeftID, true); - break; - case Track::RightChannel: - theMenu->Check(OnChannelRightID, true); - break; - default: - theMenu->Check(OnChannelMonoID, true); + // We only need to set check marks. Clearing checks causes problems on Linux (bug 851) + switch (t->GetChannel()) { + case Track::LeftChannel: + theMenu->Check(OnChannelLeftID, true); + break; + case Track::RightChannel: + theMenu->Check(OnChannelRightID, true); + break; + default: + theMenu->Check(OnChannelMonoID, true); + } } - theMenu->Enable(OnChannelMonoID, !t->GetLinked()); - theMenu->Enable(OnChannelLeftID, !t->GetLinked()); - theMenu->Enable(OnChannelRightID, !t->GetLinked()); - const int display = static_cast(t)->GetDisplay(); theMenu->Check( (display == WaveTrack::Waveform) ? OnWaveformID : OnSpectrumID, diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 9603c4b54..5e26f0723 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -239,7 +239,8 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel { * the track around, via a single set of code. * @param menu the menu to add the commands to. */ - virtual void BuildCommonDropMenuItems(wxMenu * menu); + static void BuildCommonDropMenuItems(wxMenu * menu); + static void BuildWaveTrackMenuItems(wxMenu * menu, bool mono); static void BuildVRulerMenuItems(wxMenu * menu, int firstId, const wxArrayString &names); virtual bool IsAudioActive(); virtual bool IsUnsafe(); @@ -819,7 +820,8 @@ protected: wxCursor *mStretchRightCursor; #endif - wxMenu *mWaveTrackMenu; + wxMenu *mMonoTrackMenu; + wxMenu *mStereoTrackMenu; wxMenu *mNoteTrackMenu; wxMenu *mTimeTrackMenu; wxMenu *mLabelTrackMenu;