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

static UndoManager::Get()...

... not member functions of AudacityProject
This commit is contained in:
Paul Licameli 2019-01-21 17:45:03 -05:00
parent b5a57682b6
commit 72b7c776a8
12 changed files with 69 additions and 39 deletions

View File

@ -119,10 +119,10 @@ LyricsPanel::LyricsPanel(wxWindow* parent, wxWindowID id,
parent->Bind(wxEVT_SHOW, &LyricsPanel::OnShow, this);
auto undoManager = project->GetUndoManager();
undoManager->Bind(EVT_UNDO_PUSHED, &LyricsPanel::UpdateLyrics, this);
undoManager->Bind(EVT_UNDO_MODIFIED, &LyricsPanel::UpdateLyrics, this);
undoManager->Bind(EVT_UNDO_RESET, &LyricsPanel::UpdateLyrics, this);
auto &undoManager = UndoManager::Get( *project );
undoManager.Bind(EVT_UNDO_PUSHED, &LyricsPanel::UpdateLyrics, this);
undoManager.Bind(EVT_UNDO_MODIFIED, &LyricsPanel::UpdateLyrics, this);
undoManager.Bind(EVT_UNDO_RESET, &LyricsPanel::UpdateLyrics, this);
wxTheApp->Bind(EVT_AUDIOIO_PLAYBACK, &LyricsPanel::OnStartStop, this);
wxTheApp->Bind(EVT_AUDIOIO_CAPTURE, &LyricsPanel::OnStartStop, this);

View File

@ -303,7 +303,7 @@ void MenuCreator::CreateMenusAndCommands(AudacityProject &project)
void MenuManager::ModifyUndoMenuItems(AudacityProject &project)
{
wxString desc;
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
auto &commandManager = *project.GetCommandManager();
int cur = undoManager.GetCurrentState();
@ -493,7 +493,7 @@ CommandFlag MenuManager::GetUpdateFlags
if( Clipboard::Get().Duration() > 0 )
flags |= ClipboardFlag;
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
if (undoManager.UnsavedChanges() || !project.IsProjectSaved())
flags |= UnsavedChangesFlag;

View File

@ -1058,8 +1058,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
gPrefs->Read(wxT("/FrequencySelectionFormatName"), wxT("")) ) ),
mBandwidthSelectionFormatName( NumericTextCtrl::LookupFormat(
NumericConverter::BANDWIDTH,
gPrefs->Read(wxT("/BandwidthSelectionFormatName"), wxT("")) ) ),
mUndoManager(std::make_unique<UndoManager>())
gPrefs->Read(wxT("/BandwidthSelectionFormatName"), wxT("")) ) )
, mCommandManager( std::make_unique<CommandManager>() )
{
auto &project = *this;
@ -2562,7 +2561,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
// We may not bother to prompt the user to save, if the
// project is now empty.
if (event.CanVeto() && (mEmptyCanBeDirty || bHasTracks)) {
if (GetUndoManager()->UnsavedChanges()) {
if ( UndoManager::Get( project ).UnsavedChanges() ) {
TitleRestorer Restorer( this );// RAII
/* i18n-hint: The first %s numbers the project, the second %s is the project name.*/
wxString Title = wxString::Format(_("%sSave changes to %s?"), Restorer.sProjNumber, Restorer.sProjName);
@ -2678,7 +2677,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
// This must be done before the following Deref() since it holds
// references to the DirManager.
GetUndoManager()->ClearStates();
UndoManager::Get( project ).ClearStates();
// MM: Tell the DirManager it can now DELETE itself
// if it finds it is no longer needed. If it is still
@ -3854,6 +3853,7 @@ bool AudacityProject::DoSave (const bool fromSaveAs,
{
// See explanation above
// ProjectDisabler disabler(this);
auto &proj = *this;
wxASSERT_MSG(!bWantSaveCopy || fromSaveAs, "Copy Project SHOULD only be availabele from SaveAs");
@ -3864,7 +3864,7 @@ bool AudacityProject::DoSave (const bool fromSaveAs,
auto &tracks = TrackList::Get( project );
if ( ! tracks.Any() )
{
if (GetUndoManager()->UnsavedChanges() && mEmptyCanBeDirty) {
if ( UndoManager::Get( proj ).UnsavedChanges() && mEmptyCanBeDirty) {
int result = AudacityMessageBox(_("Your project is now empty.\nIf saved, the project will have no tracks.\n\nTo save any previously open tracks:\nClick 'No', Edit > Undo until all tracks\nare open, then File > Save Project.\n\nSave anyway?"),
_("Warning - Empty Project"),
wxYES_NO | wxICON_QUESTION, this);
@ -4074,8 +4074,7 @@ bool AudacityProject::DoSave (const bool fromSaveAs,
mLastSavedTracks->Clear();
mLastSavedTracks = TrackList::Create();
auto &project = *this;
auto &tracks = TrackList::Get( project );
auto &tracks = TrackList::Get( proj );
for ( auto t : tracks.Any() ) {
mLastSavedTracks->Add(t->Duplicate());
@ -4085,7 +4084,7 @@ bool AudacityProject::DoSave (const bool fromSaveAs,
// wt->MarkSaved();
}
GetUndoManager()->StateSaved();
UndoManager::Get( proj ).StateSaved();
}
// If we get here, saving the project was successful, so we can DELETE
@ -4634,14 +4633,15 @@ void AudacityProject::InitialState()
auto &project = *this;
auto &tracks = TrackList::Get( project );
auto &viewInfo = ViewInfo::Get( project );
auto &undoManager = UndoManager::Get( project );
GetUndoManager()->ClearStates();
undoManager.ClearStates();
GetUndoManager()->PushState(
undoManager.PushState(
&tracks, viewInfo.selectedRegion, mTags,
_("Created new project"), wxT(""));
GetUndoManager()->StateSaved();
undoManager.StateSaved();
GetMenuManager(*this).ModifyUndoMenuItems(*this);
@ -4652,7 +4652,8 @@ bool AudacityProject::UndoAvailable()
{
auto &project = *this;
auto &tracks = TrackList::Get( project );
return GetUndoManager()->UndoAvailable() &&
auto &undoManager = UndoManager::Get( project );
return undoManager.UndoAvailable() &&
!tracks.HasPendingTracks();
}
@ -4660,8 +4661,9 @@ bool AudacityProject::RedoAvailable()
{
auto &project = *this;
auto &tracks = TrackList::Get( project );
return GetUndoManager()->RedoAvailable() &&
!tracks.HasPendingTracks();
auto &undoManager = UndoManager::Get( project );
return undoManager.RedoAvailable() &&
!tracks.HasPendingTracks();
}
void AudacityProject::PushState(const wxString &desc, const wxString &shortDesc)
@ -4676,7 +4678,8 @@ void AudacityProject::PushState(const wxString &desc,
auto &project = *this;
auto &tracks = TrackList::Get( project );
auto &viewInfo = ViewInfo::Get( project );
GetUndoManager()->PushState(
auto &undoManager = UndoManager::Get( project );
undoManager.PushState(
&tracks, viewInfo.selectedRegion, mTags,
desc, shortDesc, flags);
@ -4696,7 +4699,9 @@ void AudacityProject::PushState(const wxString &desc,
void AudacityProject::RollbackState()
{
SetStateTo(GetUndoManager()->GetCurrentState());
auto &project = *this;
auto &undoManager = UndoManager::Get( project );
SetStateTo( undoManager.GetCurrentState() );
}
void AudacityProject::ModifyState(bool bWantsAutoSave)
@ -4704,7 +4709,8 @@ void AudacityProject::ModifyState(bool bWantsAutoSave)
auto &project = *this;
auto &tracks = TrackList::Get( project );
auto &viewInfo = ViewInfo::Get( project );
GetUndoManager()->ModifyState(
auto &undoManager = UndoManager::Get( project );
undoManager.ModifyState(
&tracks, viewInfo.selectedRegion, mTags);
if (bWantsAutoSave)
AutoSave();
@ -4772,7 +4778,9 @@ void AudacityProject::PopState(const UndoState &state)
void AudacityProject::SetStateTo(unsigned int n)
{
GetUndoManager()->SetStateTo(n,
auto &project = *this;
auto &undoManager = UndoManager::Get( project );
undoManager.SetStateTo(n,
[this]( const UndoState &state ){ PopState(state); } );
HandleResize();
@ -5354,7 +5362,8 @@ void AudacityProject::ResetProjectToEmpty() {
projectFileIO.ResetProjectFileIO();
mDirty = false;
GetUndoManager()->ClearStates();
auto &undoManager = UndoManager::Get( project );
undoManager.ClearStates();
}
void AudacityProject::ResetProjectFileIO()
@ -5545,8 +5554,10 @@ MixerBoardFrame* AudacityProject::GetMixerBoardFrame(bool create)
HistoryWindow *AudacityProject::GetHistoryWindow(bool create)
{
auto &project = *this;
auto &undoManager = UndoManager::Get( project );
if (create && !mHistoryWindow)
mHistoryWindow = safenew HistoryWindow{ this, GetUndoManager() };
mHistoryWindow = safenew HistoryWindow{ this, &undoManager };
return mHistoryWindow;
}

View File

@ -200,8 +200,6 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
AudioIOStartStreamOptions GetDefaultPlayOptions();
AudioIOStartStreamOptions GetSpeedPlayOptions();
UndoManager *GetUndoManager() { return mUndoManager.get(); }
sampleFormat GetDefaultFormat() { return mDefaultFormat; }
double GetRate() const { return mRate; }
@ -565,8 +563,6 @@ public:
static ODLock &AllProjectDeleteMutex();
private:
// History/Undo manager
std::unique_ptr<UndoManager> mUndoManager;
bool mDirty{ false };
// Commands

View File

@ -28,6 +28,7 @@ UndoManager
#include "BlockFile.h"
#include "Clipboard.h"
#include "Diags.h"
#include "Project.h"
#include "Sequence.h"
#include "WaveClip.h"
#include "WaveTrack.h" // temp
@ -63,6 +64,20 @@ struct UndoStackElem {
wxString shortDescription;
};
static const AudacityProject::AttachedObjects::RegisteredFactory key{
[](AudacityProject&) { return std::make_unique<UndoManager>(); }
};
UndoManager &UndoManager::Get( AudacityProject &project )
{
return project.AttachedObjects::Get< UndoManager >( key );
}
const UndoManager &UndoManager::Get( const AudacityProject &project )
{
return Get( const_cast< AudacityProject & >( project ) );
}
UndoManager::UndoManager()
{
current = -1;

View File

@ -52,6 +52,7 @@
#include <vector>
#include <wx/event.h> // to declare custom event types
#include "ondemand/ODTaskThread.h"
#include "ClientData.h"
#include "SelectedRegion.h"
// Events emitted by UndoManager for the use of listeners
@ -67,6 +68,7 @@ wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_UNDO_MODIFIED, wxCommandEvent);
// contents did not change other than the pointer to current state
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_UNDO_RESET, wxCommandEvent);
class AudacityProject;
class Tags;
class Track;
class TrackList;
@ -102,8 +104,14 @@ inline UndoPush operator | (UndoPush a, UndoPush b)
inline UndoPush operator & (UndoPush a, UndoPush b)
{ return static_cast<UndoPush>(static_cast<int>(a) & static_cast<int>(b)); }
class AUDACITY_DLL_API UndoManager : public wxEvtHandler {
class AUDACITY_DLL_API UndoManager
: public wxEvtHandler
, public ClientData::Base
{
public:
static UndoManager &Get( AudacityProject &project );
static const UndoManager &Get( const AudacityProject &project );
UndoManager();
~UndoManager();

View File

@ -294,7 +294,7 @@ void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
AudacityProject *project = GetActiveProject();
bool success = false;
auto state = project->GetUndoManager()->GetCurrentState();
auto state = UndoManager::Get( *project ).GetCurrentState();
auto cleanup = finally( [&] {
if(!success)
project->SetStateTo(state);

View File

@ -691,7 +691,7 @@ double DoClipMove
void DoClipLeftOrRight
(AudacityProject &project, bool right, bool keyUp )
{
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
if (keyUp) {
undoManager.StopConsolidating();

View File

@ -223,7 +223,7 @@ bool DoEditMetadata
void DoUndo(AudacityProject &project)
{
auto trackPanel = project.GetTrackPanel();
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
if (!project.UndoAvailable()) {
AudacityMessageBox(_("Nothing to undo"));
@ -258,7 +258,7 @@ void OnRedo(const CommandContext &context)
{
auto &project = context.project;
auto trackPanel = project.GetTrackPanel();
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
if (!project.RedoAvailable()) {
AudacityMessageBox(_("Nothing to redo"));

View File

@ -905,7 +905,7 @@ void OnResample(const CommandContext &context)
auto &project = context.project;
auto projectRate = project.GetRate();
auto &tracks = TrackList::Get( project );
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
int newRate;

View File

@ -400,7 +400,7 @@ void OnRecord2ndChoice(const CommandContext &context)
void OnTimerRecord(const CommandContext &context)
{
auto &project = context.project;
auto &undoManager = *project.GetUndoManager();
auto &undoManager = UndoManager::Get( project );
// MY: Due to improvements in how Timer Recording saves and/or exports
// it is now safer to disable Timer Recording when there is more than

View File

@ -135,7 +135,7 @@ void ODTask::DoSome(float amountWork)
if(IsTaskAssociatedWithProject(gAudacityProjects[i].get()))
{
//mark the changes so that the project can be resaved.
gAudacityProjects[i]->GetUndoManager()->SetODChangesFlag();
UndoManager::Get( *gAudacityProjects[i] ).SetODChangesFlag();
break;
}
}
@ -161,7 +161,7 @@ void ODTask::DoSome(float amountWork)
//this assumes tasks are only associated with one project.
gAudacityProjects[i]->GetEventHandler()->AddPendingEvent(event);
//mark the changes so that the project can be resaved.
gAudacityProjects[i]->GetUndoManager()->SetODChangesFlag();
UndoManager::Get( *gAudacityProjects[i] ).SetODChangesFlag();
break;
}
}