1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-07 23:51:14 +02:00

Cleanup of Menus.* after moving most things out of them

This commit is contained in:
Paul Licameli 2018-10-24 11:06:46 -04:00
commit 7c7aab1648
13 changed files with 259 additions and 391 deletions

View File

@ -722,16 +722,16 @@ bool MacroCommands::ApplyEffectCommand(
// and apply the effect...
res = PluginActions::DoAudacityCommand(ID,
Context,
MenuCommandHandler::OnEffectFlags::kConfigured |
MenuCommandHandler::OnEffectFlags::kSkipState |
MenuCommandHandler::OnEffectFlags::kDontRepeatLast);
PluginActions::kConfigured |
PluginActions::kSkipState |
PluginActions::kDontRepeatLast);
else
// and apply the effect...
res = PluginActions::DoEffect(ID,
Context,
MenuCommandHandler::OnEffectFlags::kConfigured |
MenuCommandHandler::OnEffectFlags::kSkipState |
MenuCommandHandler::OnEffectFlags::kDontRepeatLast);
PluginActions::kConfigured |
PluginActions::kSkipState |
PluginActions::kDontRepeatLast);
}
return res;

View File

@ -11,17 +11,7 @@
*******************************************************************//**
\file Menus.cpp
\brief Functions that provide most of the menu actions.
This file implements the method that creates the menu bar, plus
most of the methods that get called when you select an item
from a menu.
*//****************************************************************//**
\class MenuCommandHandler
\brief MenuCommandHandler contains many command handlers for individual
menu items.
\brief Functions for building toobar menus and enabling and disabling items
*//****************************************************************//**
@ -37,75 +27,25 @@ menu items.
#include "Audacity.h"
#include "Menus.h"
#include "commands/CommandManager.h"
#include "commands/CommandContext.h"
#include <cfloat>
#include <iterator>
#include <algorithm>
#include <limits>
#include <math.h>
#include <wx/defs.h>
#include <wx/docview.h>
#include <wx/filedlg.h>
#include <wx/textfile.h>
#include <wx/textdlg.h>
#include <wx/progdlg.h>
#include <wx/scrolbar.h>
#include <wx/ffile.h>
#include <wx/statusbr.h>
#include <wx/utils.h>
#include "TrackPanel.h"
#include "widgets/Ruler.h"
#include "effects/EffectManager.h"
#include "AudacityApp.h"
#include "AudioIO.h"
#include "float_cast.h"
#include "LabelTrack.h"
#include "import/ImportRaw.h"
#include "prefs/PrefsDialog.h"
#include "prefs/PlaybackPrefs.h"
#include "LyricsWindow.h"
#include "MixerBoard.h"
#include "Project.h"
#include "Internat.h"
#include "FileFormats.h"
#include "ModuleManager.h"
#include "Prefs.h"
#ifdef USE_MIDI
#include "NoteTrack.h"
#endif // USE_MIDI
#include "ondemand/ODManager.h"
#include "prefs/BatchPrefs.h"
#include "toolbars/ToolManager.h"
#include "toolbars/ControlToolBar.h"
#include "toolbars/EditToolBar.h"
#include "tracks/ui/SelectHandle.h"
#include "widgets/LinkingHtmlWindow.h"
#include "Experimental.h"
#include "PlatformCompatibility.h"
#include "Prefs.h"
#include "Project.h"
#include "TrackPanel.h"
#include "UndoManager.h"
#include "WaveTrack.h"
#include "commands/CommandManager.h"
#include "prefs/TracksPrefs.h"
#include "widgets/ErrorDialog.h"
#include "./commands/AudacityCommand.h"
static const AudacityProject::RegisteredAttachedObjectFactory factory{ []{
return std::make_unique< MenuCommandHandler >();
} };
#include "toolbars/ControlToolBar.h"
#include "toolbars/ToolManager.h"
#include "widgets/Ruler.h"
PrefsListener::~PrefsListener()
{
@ -115,34 +55,17 @@ void PrefsListener::UpdatePrefs()
{
}
MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project)
{
return static_cast<MenuCommandHandler&>(
project.GetAttachedObject( factory ) );
}
MenuManager &GetMenuManager(AudacityProject &project)
{ return *project.mMenuManager; }
MenuCommandHandler::MenuCommandHandler()
MenuCreator::MenuCreator()
{
}
MenuCommandHandler::~MenuCommandHandler()
{
}
MenuCreator::MenuCreator(){
}
MenuCreator::~MenuCreator()
{
}
void MenuCommandHandler::UpdatePrefs()
{
}
void MenuManager::UpdatePrefs()
{
bool bSelectAllIfNone;
@ -311,14 +234,6 @@ void VisitItem( AudacityProject &project, MenuTable::BaseItem *pItem )
/// changes in configured preferences - for example changes in key-bindings
/// affect the short-cut key legend that appears beside each command,
// To supply the "finder" argument in AddItem calls
static CommandHandlerObject &findMenuCommandHandler(AudacityProject &project)
{ return GetMenuCommandHandler( project ); }
#define FN(X) findMenuCommandHandler, \
static_cast<CommandFunctorPointer>(& MenuCommandHandler :: X)
#define XXO(X) _(X), wxString{X}.Contains("...")
MenuTable::BaseItemPtr FileMenu( AudacityProject& );
MenuTable::BaseItemPtr EditMenu( AudacityProject& );
@ -382,9 +297,6 @@ void MenuCreator::CreateMenusAndCommands(AudacityProject &project)
#endif
}
#undef XXO
#undef FN
// TODO: This surely belongs in CommandManager?
void MenuManager::ModifyUndoMenuItems(AudacityProject &project)
{
@ -447,10 +359,6 @@ void MenuCreator::RebuildMenuBar(AudacityProject &project)
ModuleManager::Get().Dispatch(MenusRebuilt);
}
void AudacityProject::RebuildOtherMenus()
{
}
CommandFlag MenuManager::GetFocusedFrame(AudacityProject &project)
{
wxWindow *w = wxWindow::FindFocus();
@ -647,32 +555,6 @@ CommandFlag MenuManager::GetUpdateFlags
return flags;
}
namespace SelectActions {
void DoSelectSomething(AudacityProject &project);
}
// Select the full time range, if no
// time range is selected.
void AudacityProject::SelectAllIfNone()
{
auto flags = GetMenuManager(*this).GetUpdateFlags(*this);
if(!(flags & TracksSelectedFlag) ||
(mViewInfo.selectedRegion.isPoint()))
SelectActions::DoSelectSomething(*this);
}
namespace TransportActions {
void DoStop( AudacityProject & );
}
// Stop playing or recording, if paused.
void AudacityProject::StopIfPaused()
{
auto flags = GetMenuManager(*this).GetUpdateFlags(*this);
if( flags & PausedFlag )
TransportActions::DoStop(*this);
}
void MenuManager::ModifyAllProjectToolbarMenus()
{
AProjectArray::iterator i;
@ -837,85 +719,11 @@ void MenuManager::UpdateMenus(AudacityProject &project, bool checkActive)
MenuManager::ModifyToolbarMenus(project);
}
//sort based on flags. see Project.h for sort flags
void AudacityProject::SortTracks(int flags)
{
auto GetTime = [](const Track *t) {
return t->TypeSwitch< double >(
[&](const WaveTrack* w) {
auto stime = w->GetEndTime();
int ndx;
for (ndx = 0; ndx < w->GetNumClips(); ndx++) {
const auto c = w->GetClipByIndex(ndx);
if (c->GetNumSamples() == 0)
continue;
stime = std::min(stime, c->GetStartTime());
}
return stime;
},
[&](const LabelTrack* l) {
return l->GetStartTime();
}
);
};
size_t ndx = 0;
// This one place outside of TrackList where we must use undisguised
// std::list iterators! Avoid this elsewhere!
std::vector<TrackNodePointer> arr;
arr.reserve(mTracks->size());
// First find the permutation.
// This routine, very unusually, deals with the underlying stl list
// iterators, not with TrackIter! Dangerous!
for (auto iter = mTracks->ListOfTracks::begin(),
end = mTracks->ListOfTracks::end(); iter != end; ++iter) {
const auto &track = *iter;
if ( !track->IsLeader() )
// keep channels contiguous
ndx++;
else {
auto size = arr.size();
for (ndx = 0; ndx < size;) {
Track &arrTrack = **arr[ndx].first;
auto channels = TrackList::Channels(&arrTrack);
if(flags & kAudacitySortByName) {
//do case insensitive sort - cmpNoCase returns less than zero if the string is 'less than' its argument
//also if we have case insensitive equality, then we need to sort by case as well
//We sort 'b' before 'B' accordingly. We uncharacteristically use greater than for the case sensitive
//compare because 'b' is greater than 'B' in ascii.
auto cmpValue = track->GetName().CmpNoCase(arrTrack.GetName());
if ( cmpValue < 0 ||
( 0 == cmpValue &&
track->GetName().CompareTo(arrTrack.GetName()) > 0 ) )
break;
}
//sort by time otherwise
else if(flags & kAudacitySortByTime) {
auto time1 = TrackList::Channels(track.get()).min( GetTime );
//get candidate's (from sorted array) time
auto time2 = channels.min( GetTime );
if (time1 < time2)
break;
}
ndx += channels.size();
}
}
arr.insert(arr.begin() + ndx, TrackNodePointer{iter, mTracks.get()});
}
// Now apply the permutation
mTracks->Permute(arr);
}
/// The following method moves to the previous track
/// selecting and unselecting depending if you are on the start of a
/// block or not.
void MenuCommandHandler::RebuildAllMenuBars()
void MenuCreator::RebuildAllMenuBars()
{
for( size_t i = 0; i < gAudacityProjects.size(); i++ ) {
AudacityProject *p = gAudacityProjects[i].get();
@ -933,112 +741,3 @@ void MenuCommandHandler::RebuildAllMenuBars()
#endif
}
}
void AudacityProject::SelectNone()
{
for (auto t : GetTracks()->Any())
t->SetSelected(false);
mTrackPanel->Refresh(false);
if (mMixerBoard)
mMixerBoard->Refresh(false);
}
//
// View Menu
//
double AudacityProject::GetScreenEndTime() const
{
return mTrackPanel->GetScreenEndTime();
}
void AudacityProject::ZoomInByFactor( double ZoomFactor )
{
// LLL: Handling positioning differently when audio is
// actively playing. Don't do this if paused.
if ((gAudioIO->IsStreamActive(GetAudioIOToken()) != 0) && !gAudioIO->IsPaused()){
ZoomBy(ZoomFactor);
mTrackPanel->ScrollIntoView(gAudioIO->GetStreamTime());
mTrackPanel->Refresh(false);
return;
}
// DMM: Here's my attempt to get logical zooming behavior
// when there's a selection that's currently at least
// partially on-screen
const double endTime = GetScreenEndTime();
const double duration = endTime - mViewInfo.h;
bool selectionIsOnscreen =
(mViewInfo.selectedRegion.t0() < endTime) &&
(mViewInfo.selectedRegion.t1() >= mViewInfo.h);
bool selectionFillsScreen =
(mViewInfo.selectedRegion.t0() < mViewInfo.h) &&
(mViewInfo.selectedRegion.t1() > endTime);
if (selectionIsOnscreen && !selectionFillsScreen) {
// Start with the center of the selection
double selCenter = (mViewInfo.selectedRegion.t0() +
mViewInfo.selectedRegion.t1()) / 2;
// If the selection center is off-screen, pick the
// center of the part that is on-screen.
if (selCenter < mViewInfo.h)
selCenter = mViewInfo.h +
(mViewInfo.selectedRegion.t1() - mViewInfo.h) / 2;
if (selCenter > endTime)
selCenter = endTime -
(endTime - mViewInfo.selectedRegion.t0()) / 2;
// Zoom in
ZoomBy(ZoomFactor);
const double newDuration = GetScreenEndTime() - mViewInfo.h;
// Recenter on selCenter
TP_ScrollWindow(selCenter - newDuration / 2);
return;
}
double origLeft = mViewInfo.h;
double origWidth = duration;
ZoomBy(ZoomFactor);
const double newDuration = GetScreenEndTime() - mViewInfo.h;
double newh = origLeft + (origWidth - newDuration) / 2;
// MM: Commented this out because it was confusing users
/*
// make sure that the *right-hand* end of the selection is
// no further *left* than 1/3 of the way across the screen
if (mViewInfo.selectedRegion.t1() < newh + mViewInfo.screen / 3)
newh = mViewInfo.selectedRegion.t1() - mViewInfo.screen / 3;
// make sure that the *left-hand* end of the selection is
// no further *right* than 2/3 of the way across the screen
if (mViewInfo.selectedRegion.t0() > newh + mViewInfo.screen * 2 / 3)
newh = mViewInfo.selectedRegion.t0() - mViewInfo.screen * 2 / 3;
*/
TP_ScrollWindow(newh);
}
void AudacityProject::ZoomOutByFactor( double ZoomFactor )
{
//Zoom() may change these, so record original values:
const double origLeft = mViewInfo.h;
const double origWidth = GetScreenEndTime() - origLeft;
ZoomBy(ZoomFactor);
const double newWidth = GetScreenEndTime() - mViewInfo.h;
const double newh = origLeft + (origWidth - newWidth) / 2;
// newh = (newh > 0) ? newh : 0;
TP_ScrollWindow(newh);
}
//

View File

@ -12,11 +12,7 @@
#include "Experimental.h"
#include <memory>
#include <vector>
#include <wx/event.h>
#include "SelectedRegion.h"
#include "commands/CommandFunctors.h"
#include <wx/arrstr.h>
class AudacityProject;
class CommandContext;
@ -42,36 +38,6 @@ public:
virtual void UpdatePrefs(); // default is no-op
};
struct MenuCommandHandler final
: public CommandHandlerObject // MUST be the first base class!
, public PrefsListener
{
MenuCommandHandler();
~MenuCommandHandler();
public:
// Effect Menu
struct OnEffectFlags
{
// No flags specified
static const int kNone = 0x00;
// Flag used to disable prompting for configuration parameteres.
static const int kConfigured = 0x01;
// Flag used to disable saving the state after processing.
static const int kSkipState = 0x02;
// Flag used to disable "Repeat Last Effect"
static const int kDontRepeatLast = 0x04;
};
static void RebuildAllMenuBars();
public:
void UpdatePrefs() override;
};
class MenuCreator
{
public:
@ -80,6 +46,8 @@ public:
void CreateMenusAndCommands(AudacityProject &project);
void RebuildMenuBar(AudacityProject &project);
static void RebuildAllMenuBars();
public:
CommandFlag mLastFlags;
@ -101,16 +69,18 @@ public:
// If checkActive, do not do complete flags testing on an
// inactive project as it is needlessly expensive.
CommandFlag GetUpdateFlags(AudacityProject &project, bool checkActive = false);
CommandFlag GetUpdateFlags(
AudacityProject &project, bool checkActive = false);
void UpdatePrefs();
// Command Handling
bool ReportIfActionNotAllowed
( AudacityProject &project,
const wxString & Name, CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
bool TryToMakeActionAllowed
( AudacityProject &project,
CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
bool ReportIfActionNotAllowed(
AudacityProject &project,
const wxString & Name, CommandFlag & flags, CommandFlag flagsRqd,
CommandFlag mask );
bool TryToMakeActionAllowed(
AudacityProject &project,
CommandFlag & flags, CommandFlag flagsRqd, CommandFlag mask );
private:
@ -122,10 +92,10 @@ private:
};
MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project);
MenuManager &GetMenuManager(AudacityProject &project);
// Exported helper functions from various menu handling source files
namespace FileActions {
AudacityProject *DoImportMIDI(
AudacityProject *pProject, const wxString &fileName );
@ -173,6 +143,16 @@ void DoRemoveTracks( AudacityProject & );
}
namespace PluginActions {
enum : unsigned {
// No flags specified
kNone = 0x00,
// Flag used to disable prompting for configuration parameteres.
kConfigured = 0x01,
// Flag used to disable saving the state after processing.
kSkipState = 0x02,
// Flag used to disable "Repeat Last Effect"
kDontRepeatLast = 0x04,
};
bool DoEffect(
const PluginID & ID, const CommandContext & context, unsigned flags );
bool DoAudacityCommand(
@ -185,6 +165,3 @@ void DoShowLog( AudacityProject& );
}
#endif

View File

@ -3124,7 +3124,7 @@ void AudacityProject::OpenFile(const wxString &fileNameArg, bool addtohistory)
#ifdef EXPERIMENTAL_DRAG_DROP_PLUG_INS
// Is it a plug-in?
if (PluginManager::Get().DropFile(fileName)) {
MenuCommandHandler::RebuildAllMenuBars();
MenuCreator::RebuildAllMenuBars();
}
else
// No, so import.
@ -4419,7 +4419,7 @@ bool AudacityProject::Import(const wxString &fileName, WaveTrackArray* pTrackArr
PluginActions::DoEffect(
EffectManager::Get().GetEffectByIdentifier(wxT("Normalize")),
context,
MenuCommandHandler::OnEffectFlags::kConfigured);
PluginActions::kConfigured);
}
// This is a no-fail:
@ -6245,3 +6245,124 @@ ContrastDialog *AudacityProject::GetContrastDialog(bool create)
return mContrastDialog.get();
}
double AudacityProject::GetScreenEndTime() const
{
return mTrackPanel->GetScreenEndTime();
}
void AudacityProject::SelectNone()
{
for (auto t : GetTracks()->Any())
t->SetSelected(false);
mTrackPanel->Refresh(false);
if (mMixerBoard)
mMixerBoard->Refresh(false);
}
void AudacityProject::ZoomInByFactor( double ZoomFactor )
{
// LLL: Handling positioning differently when audio is
// actively playing. Don't do this if paused.
if ((gAudioIO->IsStreamActive(GetAudioIOToken()) != 0) &&
!gAudioIO->IsPaused()){
ZoomBy(ZoomFactor);
mTrackPanel->ScrollIntoView(gAudioIO->GetStreamTime());
mTrackPanel->Refresh(false);
return;
}
// DMM: Here's my attempt to get logical zooming behavior
// when there's a selection that's currently at least
// partially on-screen
const double endTime = GetScreenEndTime();
const double duration = endTime - mViewInfo.h;
bool selectionIsOnscreen =
(mViewInfo.selectedRegion.t0() < endTime) &&
(mViewInfo.selectedRegion.t1() >= mViewInfo.h);
bool selectionFillsScreen =
(mViewInfo.selectedRegion.t0() < mViewInfo.h) &&
(mViewInfo.selectedRegion.t1() > endTime);
if (selectionIsOnscreen && !selectionFillsScreen) {
// Start with the center of the selection
double selCenter = (mViewInfo.selectedRegion.t0() +
mViewInfo.selectedRegion.t1()) / 2;
// If the selection center is off-screen, pick the
// center of the part that is on-screen.
if (selCenter < mViewInfo.h)
selCenter = mViewInfo.h +
(mViewInfo.selectedRegion.t1() - mViewInfo.h) / 2;
if (selCenter > endTime)
selCenter = endTime -
(endTime - mViewInfo.selectedRegion.t0()) / 2;
// Zoom in
ZoomBy(ZoomFactor);
const double newDuration = GetScreenEndTime() - mViewInfo.h;
// Recenter on selCenter
TP_ScrollWindow(selCenter - newDuration / 2);
return;
}
double origLeft = mViewInfo.h;
double origWidth = duration;
ZoomBy(ZoomFactor);
const double newDuration = GetScreenEndTime() - mViewInfo.h;
double newh = origLeft + (origWidth - newDuration) / 2;
// MM: Commented this out because it was confusing users
/*
// make sure that the *right-hand* end of the selection is
// no further *left* than 1/3 of the way across the screen
if (mViewInfo.selectedRegion.t1() < newh + mViewInfo.screen / 3)
newh = mViewInfo.selectedRegion.t1() - mViewInfo.screen / 3;
// make sure that the *left-hand* end of the selection is
// no further *right* than 2/3 of the way across the screen
if (mViewInfo.selectedRegion.t0() > newh + mViewInfo.screen * 2 / 3)
newh = mViewInfo.selectedRegion.t0() - mViewInfo.screen * 2 / 3;
*/
TP_ScrollWindow(newh);
}
void AudacityProject::ZoomOutByFactor( double ZoomFactor )
{
//Zoom() may change these, so record original values:
const double origLeft = mViewInfo.h;
const double origWidth = GetScreenEndTime() - origLeft;
ZoomBy(ZoomFactor);
const double newWidth = GetScreenEndTime() - mViewInfo.h;
const double newh = origLeft + (origWidth - newWidth) / 2;
// newh = (newh > 0) ? newh : 0;
TP_ScrollWindow(newh);
}
// Select the full time range, if no
// time range is selected.
void AudacityProject::SelectAllIfNone()
{
auto flags = GetMenuManager(*this).GetUpdateFlags(*this);
if(!(flags & TracksSelectedFlag) ||
(mViewInfo.selectedRegion.isPoint()))
SelectActions::DoSelectSomething(*this);
}
// Stop playing or recording, if paused.
void AudacityProject::StopIfPaused()
{
auto flags = GetMenuManager(*this).GetUpdateFlags(*this);
if( flags & PausedFlag )
TransportActions::DoStop(*this);
}

View File

@ -169,7 +169,6 @@ class WaveTrack;
#include "./commands/CommandFlag.h"
#include "../include/audacity/EffectInterface.h"
struct MenuCommandHandler;
class MenuManager;
class PrefsListener;
@ -375,7 +374,6 @@ public:
static void CaptureKeyboard(wxWindow *handler);
static void ReleaseKeyboard(wxWindow *handler);
void RebuildOtherMenus();
void MayStartMonitoring();
@ -831,7 +829,6 @@ private:
std::unique_ptr<MenuManager> mMenuManager;
public:
friend MenuCommandHandler &GetMenuCommandHandler(AudacityProject &project);
friend MenuManager &GetMenuManager(AudacityProject &project);
class PlaybackScroller final : public wxEvtHandler

View File

@ -1536,7 +1536,7 @@ bool CommandManager::HandleMenuID(int id, CommandFlag flags, CommandMask mask)
factories.push_back(&keyConfigPrefsFactory);
GlobalPrefsDialog dialog(GetActiveProject(), factories);
dialog.ShowModal();
MenuCommandHandler::RebuildAllMenuBars();
MenuCreator::RebuildAllMenuBars();
return true;
}
#endif
@ -1589,7 +1589,7 @@ bool CommandManager::HandleTextualCommand(const wxString & Str, const CommandCon
{
return PluginActions::DoEffect(
plug->GetID(), context,
MenuCommandHandler::OnEffectFlags::kConfigured);
PluginActions::kConfigured);
}
plug = pm.GetNextPlugin(PluginTypeEffect);
}

View File

@ -769,7 +769,7 @@ bool Effect::Apply()
//
// It should callback to the EffectManager to kick off the processing
return PluginActions::DoEffect(GetID(), context,
MenuCommandHandler::OnEffectFlags::kConfigured);
PluginActions::kConfigured);
}
void Effect::Preview()

View File

@ -307,7 +307,7 @@ void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
{
if (!PluginActions::DoEffect(mEffects[i]->GetID(),
*project,
AudacityProject::OnEffectFlags::kConfigured))
PluginActions::kConfigured))
// If any effect fails (or throws), then stop.
return;
}

View File

@ -178,7 +178,6 @@ void DoReloadPreferences( AudacityProject &project )
AudacityProject *p = gAudacityProjects[i].get();
GetMenuManager(*p).RebuildMenuBar(*p);
p->RebuildOtherMenus();
// TODO: The comment below suggests this workaround is obsolete.
#if defined(__WXGTK__)
// Workaround for:
@ -1030,7 +1029,6 @@ void OnPreferences(const CommandContext &context)
AudacityProject *p = gAudacityProjects[i].get();
GetMenuManager(*p).RebuildMenuBar(*p);
p->RebuildOtherMenus();
// TODO: The comment below suggests this workaround is obsolete.
#if defined(__WXGTK__)
// Workaround for:

View File

@ -23,7 +23,7 @@ void DoManagePluginsMenu
(AudacityProject &project, EffectType type)
{
if (PluginManager::Get().ShowManager(&project, type))
MenuCommandHandler::RebuildAllMenuBars();
MenuCreator::RebuildAllMenuBars();
}
bool CompareEffectsByName(const PluginDescriptor *a, const PluginDescriptor *b)
@ -404,7 +404,7 @@ bool DoEffect(
// Make sure there's no activity since the effect is about to be applied
// to the project's tracks. Mainly for Apply during RTP, but also used
// for batch commands
if (flags & MenuCommandHandler::OnEffectFlags::kConfigured)
if (flags & kConfigured)
{
TransportActions::DoStop(project);
project.SelectAllIfNone();
@ -443,22 +443,22 @@ bool DoEffect(
success = em.DoEffect(ID, &project, rate,
tracks, trackFactory, &selectedRegion,
(flags & MenuCommandHandler::OnEffectFlags::kConfigured) == 0);
(flags & kConfigured) == 0);
if (!success)
return false;
if (em.GetSkipStateFlag())
flags = flags | MenuCommandHandler::OnEffectFlags::kSkipState;
flags = flags | kSkipState;
if (!(flags & MenuCommandHandler::OnEffectFlags::kSkipState))
if (!(flags & kSkipState))
{
wxString shortDesc = em.GetCommandName(ID);
wxString longDesc = em.GetCommandDescription(ID);
project.PushState(longDesc, shortDesc);
}
if (!(flags & MenuCommandHandler::OnEffectFlags::kDontRepeatLast))
if (!(flags & kDontRepeatLast))
{
// Only remember a successful effect, don't remember insert,
// or analyze effects.
@ -515,7 +515,7 @@ bool DoAudacityCommand(
if (!plug)
return false;
if (flags & MenuCommandHandler::OnEffectFlags::kConfigured)
if (flags & kConfigured)
{
TransportActions::DoStop(project);
// SelectAllIfNone();
@ -525,7 +525,7 @@ bool DoAudacityCommand(
bool success = em.DoAudacityCommand(ID,
context,
&project,
(flags & MenuCommandHandler::OnEffectFlags::kConfigured) == 0);
(flags & kConfigured) == 0);
if (!success)
return false;
@ -571,8 +571,7 @@ void OnRepeatLastEffect(const CommandContext &context)
auto lastEffect = GetMenuManager(context.project).mLastEffect;
if (!lastEffect.IsEmpty())
{
DoEffect(lastEffect,
context, MenuCommandHandler::OnEffectFlags::kConfigured);
DoEffect( lastEffect, context, kConfigured );
}
}
@ -682,8 +681,7 @@ void OnAudacityCommand(const CommandContext & ctx)
wxLogDebug( "Command was: %s", ctx.parameter);
// Not configured, so prompt user.
DoAudacityCommand(EffectManager::Get().GetEffectByIdentifier(ctx.parameter),
ctx,
MenuCommandHandler::OnEffectFlags::kNone);
ctx, kNone);
}
}; // struct Handler

View File

@ -427,6 +427,84 @@ long mixer_process(void *mixer, float **buffer, long n)
#endif // EXPERIMENTAL_SCOREALIGN
//sort based on flags. see Project.h for sort flags
void DoSortTracks( AudacityProject &project, int flags )
{
auto GetTime = [](const Track *t) {
return t->TypeSwitch< double >(
[&](const WaveTrack* w) {
auto stime = w->GetEndTime();
int ndx;
for (ndx = 0; ndx < w->GetNumClips(); ndx++) {
const auto c = w->GetClipByIndex(ndx);
if (c->GetNumSamples() == 0)
continue;
stime = std::min(stime, c->GetStartTime());
}
return stime;
},
[&](const LabelTrack* l) {
return l->GetStartTime();
}
);
};
size_t ndx = 0;
// This one place outside of TrackList where we must use undisguised
// std::list iterators! Avoid this elsewhere!
std::vector<TrackNodePointer> arr;
auto pTracks = project.GetTracks();
arr.reserve(pTracks->size());
// First find the permutation.
// This routine, very unusually, deals with the underlying stl list
// iterators, not with TrackIter! Dangerous!
for (auto iter = pTracks->ListOfTracks::begin(),
end = pTracks->ListOfTracks::end(); iter != end; ++iter) {
const auto &track = *iter;
if ( !track->IsLeader() )
// keep channels contiguous
ndx++;
else {
auto size = arr.size();
for (ndx = 0; ndx < size;) {
Track &arrTrack = **arr[ndx].first;
auto channels = TrackList::Channels(&arrTrack);
if(flags & kAudacitySortByName) {
//do case insensitive sort - cmpNoCase returns less than zero if
// the string is 'less than' its argument
//also if we have case insensitive equality, then we need to sort
// by case as well
//We sort 'b' before 'B' accordingly. We uncharacteristically
// use greater than for the case sensitive
//compare because 'b' is greater than 'B' in ascii.
auto cmpValue = track->GetName().CmpNoCase(arrTrack.GetName());
if ( cmpValue < 0 ||
( 0 == cmpValue &&
track->GetName().CompareTo(arrTrack.GetName()) > 0 ) )
break;
}
//sort by time otherwise
else if(flags & kAudacitySortByTime) {
auto time1 = TrackList::Channels(track.get()).min( GetTime );
//get candidate's (from sorted array) time
auto time2 = channels.min( GetTime );
if (time1 < time2)
break;
}
ndx += channels.size();
}
}
arr.insert(arr.begin() + ndx, TrackNodePointer{iter, pTracks});
}
// Now apply the permutation
pTracks->Permute(arr);
}
}
namespace TrackActions {
@ -638,7 +716,7 @@ void OnStereoToMono(const CommandContext &context)
PluginActions::DoEffect(
EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")),
context,
MenuCommandHandler::OnEffectFlags::kConfigured);
PluginActions::kConfigured);
}
void OnMixAndRender(const CommandContext &context)
@ -989,7 +1067,7 @@ void OnScoreAlign(const CommandContext &context)
void OnSortTime(const CommandContext &context)
{
auto &project = context.project;
project.SortTracks(kAudacitySortByTime);
DoSortTracks(project, kAudacitySortByTime);
project.PushState(_("Tracks sorted by time"), _("Sort by Time"));
@ -1000,7 +1078,7 @@ void OnSortTime(const CommandContext &context)
void OnSortName(const CommandContext &context)
{
auto &project = context.project;
project.SortTracks(kAudacitySortByName);
DoSortTracks(project, kAudacitySortByName);
project.PushState(_("Tracks sorted by name"), _("Sort by Name"));

View File

@ -223,7 +223,7 @@ void OnShowExtraMenus(const CommandContext &context)
gPrefs->Write(wxT("/GUI/ShowExtraMenus"), checked);
gPrefs->Flush();
commandManager->Check(wxT("ShowExtraMenus"), checked);
MenuCommandHandler::RebuildAllMenuBars();
MenuCreator::RebuildAllMenuBars();
}
void OnShowClipping(const CommandContext &context)

View File

@ -798,7 +798,7 @@ void WaveTrackMenuTable::OnSpectrogramSettings(wxCommandEvent &)
//Bug 1725 Toolbar was left greyed out.
//This solution is overkill, but does fix the problem and is what the
//prefs dialog normally does.
MenuCommandHandler::RebuildAllMenuBars();
MenuCreator::RebuildAllMenuBars();
mpData->result = RefreshCode::RefreshAll;
}
}