mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-17 16:50:26 +02:00
Limit access to global array of open projects & simplify iterations
This commit is contained in:
parent
0ae542cf08
commit
b25d3ad344
@ -466,9 +466,9 @@ static void QuitAudacity(bool bForce)
|
|||||||
// BG: unless force is true
|
// BG: unless force is true
|
||||||
|
|
||||||
// BG: Are there any projects open?
|
// BG: Are there any projects open?
|
||||||
//- if (!gAudacityProjects.empty())
|
//- if (!AllProjects{}.empty())
|
||||||
/*start+*/
|
/*start+*/
|
||||||
if (gAudacityProjects.empty())
|
if (AllProjects{}.empty())
|
||||||
{
|
{
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
Clipboard::Get().Clear();
|
Clipboard::Get().Clear();
|
||||||
@ -607,7 +607,7 @@ static gboolean save_yourself_cb(GnomeClient *client,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gAudacityProjects.empty()) {
|
if (AllProjects{}.empty()) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +808,7 @@ void AudacityApp::MacNewFile()
|
|||||||
// This method should only be used on the Mac platform
|
// This method should only be used on the Mac platform
|
||||||
// when no project windows are open.
|
// when no project windows are open.
|
||||||
|
|
||||||
if (gAudacityProjects.size() == 0) {
|
if (AllProjects{}.empty()) {
|
||||||
CreateNewAudacityProject();
|
CreateNewAudacityProject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -983,9 +983,9 @@ void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event))
|
|||||||
if (MissingAliasFilesDialog::ShouldShow()) {
|
if (MissingAliasFilesDialog::ShouldShow()) {
|
||||||
// find which project owns the blockfile
|
// find which project owns the blockfile
|
||||||
// note: there may be more than 1, but just go with the first one.
|
// note: there may be more than 1, but just go with the first one.
|
||||||
//size_t numProjects = gAudacityProjects.size();
|
//size_t numProjects = AllProjects{}.size();
|
||||||
auto marked = MissingAliasFilesDialog::Marked();
|
auto marked = MissingAliasFilesDialog::Marked();
|
||||||
AProjectHolder offendingProject = marked.second;
|
auto offendingProject = marked.second;
|
||||||
wxString missingFileName = marked.first;
|
wxString missingFileName = marked.first;
|
||||||
|
|
||||||
// if there are no projects open, don't show the warning (user has closed it)
|
// if there are no projects open, don't show the warning (user has closed it)
|
||||||
@ -2085,7 +2085,7 @@ void AudacityApp::OnMenuNew(wxCommandEvent & event)
|
|||||||
// this happens, and enable the same code to be present on
|
// this happens, and enable the same code to be present on
|
||||||
// all platforms.
|
// all platforms.
|
||||||
|
|
||||||
if(gAudacityProjects.size() == 0)
|
if(AllProjects{}.empty())
|
||||||
CreateNewAudacityProject();
|
CreateNewAudacityProject();
|
||||||
else
|
else
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@ -2101,7 +2101,7 @@ void AudacityApp::OnMenuOpen(wxCommandEvent & event)
|
|||||||
// all platforms.
|
// all platforms.
|
||||||
|
|
||||||
|
|
||||||
if(gAudacityProjects.size() == 0)
|
if(AllProjects{}.empty())
|
||||||
AudacityProject::OpenFiles(NULL);
|
AudacityProject::OpenFiles(NULL);
|
||||||
else
|
else
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@ -2117,7 +2117,7 @@ void AudacityApp::OnMenuPreferences(wxCommandEvent & event)
|
|||||||
// this happens, and enable the same code to be present on
|
// this happens, and enable the same code to be present on
|
||||||
// all platforms.
|
// all platforms.
|
||||||
|
|
||||||
if(gAudacityProjects.size() == 0) {
|
if(AllProjects{}.empty()) {
|
||||||
GlobalPrefsDialog dialog(NULL /* parent */ );
|
GlobalPrefsDialog dialog(NULL /* parent */ );
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
}
|
}
|
||||||
@ -2135,12 +2135,12 @@ void AudacityApp::OnMenuExit(wxCommandEvent & event)
|
|||||||
// all platforms.
|
// all platforms.
|
||||||
|
|
||||||
// LL: Removed "if" to allow closing based on final project count.
|
// LL: Removed "if" to allow closing based on final project count.
|
||||||
// if(gAudacityProjects.size() == 0)
|
// if(AllProjects{}.empty())
|
||||||
QuitAudacity();
|
QuitAudacity();
|
||||||
|
|
||||||
// LL: Veto quit if projects are still open. This can happen
|
// LL: Veto quit if projects are still open. This can happen
|
||||||
// if the user selected Cancel in a Save dialog.
|
// if the user selected Cancel in a Save dialog.
|
||||||
event.Skip(gAudacityProjects.size() == 0);
|
event.Skip(AllProjects{}.empty());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,8 @@ _("This will close all project windows (without saving)\nand open the Audacity B
|
|||||||
if (action != wxYES)
|
if (action != wxYES)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CloseAllProjects();
|
for ( auto pProject : AllProjects{} )
|
||||||
|
GetProjectFrame( *pProject ).Close();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BenchmarkDialog dlog(parent);
|
BenchmarkDialog dlog(parent);
|
||||||
|
@ -300,8 +300,8 @@ void DeviceManager::Rescan()
|
|||||||
// If this was not an initial scan update each device toolbar.
|
// If this was not an initial scan update each device toolbar.
|
||||||
// Hosts may have disappeared or appeared so a complete repopulate is needed.
|
// Hosts may have disappeared or appeared so a complete repopulate is needed.
|
||||||
if (m_inited) {
|
if (m_inited) {
|
||||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
for ( auto pProject : AllProjects{} ) {
|
||||||
auto &dt = DeviceToolBar::Get( *gAudacityProjects[i] );
|
auto &dt = DeviceToolBar::Get( *pProject );
|
||||||
dt.RefillCombos();
|
dt.RefillCombos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,9 +575,8 @@ CommandFlag MenuManager::GetUpdateFlags
|
|||||||
|
|
||||||
void MenuManager::ModifyAllProjectToolbarMenus()
|
void MenuManager::ModifyAllProjectToolbarMenus()
|
||||||
{
|
{
|
||||||
AProjectArray::iterator i;
|
for (auto pProject : AllProjects{}) {
|
||||||
for (i = gAudacityProjects.begin(); i != gAudacityProjects.end(); ++i) {
|
auto &project = *pProject;
|
||||||
auto &project = **i;
|
|
||||||
MenuManager::Get(project).ModifyToolbarMenus(project);
|
MenuManager::Get(project).ModifyToolbarMenus(project);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -742,9 +741,7 @@ void MenuManager::UpdateMenus(AudacityProject &project, bool checkActive)
|
|||||||
|
|
||||||
void MenuCreator::RebuildAllMenuBars()
|
void MenuCreator::RebuildAllMenuBars()
|
||||||
{
|
{
|
||||||
for( size_t i = 0; i < gAudacityProjects.size(); i++ ) {
|
for( auto p : AllProjects{} ) {
|
||||||
AudacityProject *p = gAudacityProjects[i].get();
|
|
||||||
|
|
||||||
MenuManager::Get(*p).RebuildMenuBar(*p);
|
MenuManager::Get(*p).RebuildMenuBar(*p);
|
||||||
#if defined(__WXGTK__)
|
#if defined(__WXGTK__)
|
||||||
// Workaround for:
|
// Workaround for:
|
||||||
|
@ -108,11 +108,10 @@ namespace MissingAliasFilesDialog {
|
|||||||
{
|
{
|
||||||
Lock lock{ m_LastMissingBlockFileLock };
|
Lock lock{ m_LastMissingBlockFileLock };
|
||||||
if (b) {
|
if (b) {
|
||||||
size_t numProjects = gAudacityProjects.size();
|
for ( auto pProject : AllProjects{} ) {
|
||||||
for (size_t ii = 0; ii < numProjects; ++ii) {
|
|
||||||
// search each project for the blockfile
|
// search each project for the blockfile
|
||||||
if (DirManager::Get( *gAudacityProjects[ii] ).ContainsBlockFile(b)) {
|
if (DirManager::Get( *pProject ).ContainsBlockFile(b)) {
|
||||||
m_LastMissingBlockFileProject = gAudacityProjects[ii];
|
m_LastMissingBlockFileProject = pProject;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
224
src/Project.cpp
224
src/Project.cpp
@ -170,25 +170,72 @@ scroll information. It also has some status flags.
|
|||||||
|
|
||||||
wxDEFINE_EVENT(EVT_PROJECT_STATUS_UPDATE, wxCommandEvent);
|
wxDEFINE_EVENT(EVT_PROJECT_STATUS_UPDATE, wxCommandEvent);
|
||||||
|
|
||||||
|
size_t AllProjects::size() const
|
||||||
|
{
|
||||||
|
return gAudacityProjects.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AllProjects::begin() const -> const_iterator
|
||||||
|
{
|
||||||
|
return gAudacityProjects.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AllProjects::end() const -> const_iterator
|
||||||
|
{
|
||||||
|
return gAudacityProjects.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AllProjects::rbegin() const -> const_reverse_iterator
|
||||||
|
{
|
||||||
|
return gAudacityProjects.rbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AllProjects::rend() const -> const_reverse_iterator
|
||||||
|
{
|
||||||
|
return gAudacityProjects.rend();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto AllProjects::Remove( AudacityProject &project ) -> value_type
|
||||||
|
{
|
||||||
|
ODLocker locker{ &Mutex() };
|
||||||
|
auto start = begin(), finish = end(), iter = std::find_if(
|
||||||
|
start, finish,
|
||||||
|
[&]( const value_type &ptr ){ return ptr.get() == &project; }
|
||||||
|
);
|
||||||
|
if (iter == finish)
|
||||||
|
return nullptr;
|
||||||
|
auto result = *iter;
|
||||||
|
gAudacityProjects.erase( iter );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AllProjects::Add( const value_type &pProject )
|
||||||
|
{
|
||||||
|
ODLocker locker{ &Mutex() };
|
||||||
|
gAudacityProjects.push_back( pProject );
|
||||||
|
}
|
||||||
|
|
||||||
bool AllProjects::sbClosing = false;
|
bool AllProjects::sbClosing = false;
|
||||||
bool AllProjects::sbWindowRectAlreadySaved = false;
|
bool AllProjects::sbWindowRectAlreadySaved = false;
|
||||||
|
|
||||||
bool AllProjects::Close( bool force )
|
bool AllProjects::Close( bool force )
|
||||||
{
|
{
|
||||||
ValueRestorer<bool> cleanup{ sbClosing, true };
|
ValueRestorer<bool> cleanup{ sbClosing, true };
|
||||||
if (gAudacityProjects.size())
|
if (AllProjects{}.size())
|
||||||
|
// PRL: Always did at least once before close might be vetoed
|
||||||
|
// though I don't know why that is important
|
||||||
SaveWindowSize();
|
SaveWindowSize();
|
||||||
while (gAudacityProjects.size())
|
while (AllProjects{}.size())
|
||||||
{
|
{
|
||||||
// Closing the project has global side-effect
|
// Closing the project has global side-effect
|
||||||
// of deletion from gAudacityProjects
|
// of deletion from gAudacityProjects
|
||||||
if ( force )
|
if ( force )
|
||||||
{
|
{
|
||||||
GetProjectFrame( *gAudacityProjects[0] ).Close(true);
|
GetProjectFrame( **AllProjects{}.begin() ).Close(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! GetProjectFrame( *gAudacityProjects[0] ).Close())
|
if (! GetProjectFrame( **AllProjects{}.begin() ).Close())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,14 +251,13 @@ void AllProjects::SaveWindowSize()
|
|||||||
bool validWindowForSaveWindowSize = FALSE;
|
bool validWindowForSaveWindowSize = FALSE;
|
||||||
ProjectWindow * validProject = nullptr;
|
ProjectWindow * validProject = nullptr;
|
||||||
bool foundIconizedProject = FALSE;
|
bool foundIconizedProject = FALSE;
|
||||||
size_t numProjects = gAudacityProjects.size();
|
for ( auto pProject : AllProjects{} )
|
||||||
for (size_t i = 0; i < numProjects; i++)
|
|
||||||
{
|
{
|
||||||
auto &window = ProjectWindow::Get( *gAudacityProjects[i] );
|
auto &window = ProjectWindow::Get( *pProject );
|
||||||
if (!window.IsIconized()) {
|
if (!window.IsIconized()) {
|
||||||
validWindowForSaveWindowSize = TRUE;
|
validWindowForSaveWindowSize = TRUE;
|
||||||
validProject = &window;
|
validProject = &window;
|
||||||
i = numProjects;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
foundIconizedProject = TRUE;
|
foundIconizedProject = TRUE;
|
||||||
@ -236,7 +282,7 @@ void AllProjects::SaveWindowSize()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (foundIconizedProject) {
|
if (foundIconizedProject) {
|
||||||
validProject = &ProjectWindow::Get( *gAudacityProjects[0] );
|
validProject = &ProjectWindow::Get( **AllProjects{}.begin() );
|
||||||
bool wndMaximized = validProject->IsMaximized();
|
bool wndMaximized = validProject->IsMaximized();
|
||||||
wxRect normalRect = validProject->GetNormalizedWindowState();
|
wxRect normalRect = validProject->GetNormalizedWindowState();
|
||||||
// store only the normal rectangle because the itemized rectangle
|
// store only the normal rectangle because the itemized rectangle
|
||||||
@ -274,7 +320,7 @@ void AllProjects::SaveWindowSize()
|
|||||||
sbWindowRectAlreadySaved = true;
|
sbWindowRectAlreadySaved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ODLock &AudacityProject::AllProjectDeleteMutex()
|
ODLock &AllProjects::Mutex()
|
||||||
{
|
{
|
||||||
static ODLock theMutex;
|
static ODLock theMutex;
|
||||||
return theMutex;
|
return theMutex;
|
||||||
@ -382,7 +428,7 @@ END_EVENT_TABLE()
|
|||||||
//This is a pointer to the currently-active project.
|
//This is a pointer to the currently-active project.
|
||||||
static AudacityProject *gActiveProject;
|
static AudacityProject *gActiveProject;
|
||||||
//This array holds onto all of the projects currently open
|
//This array holds onto all of the projects currently open
|
||||||
AProjectArray gAudacityProjects;
|
AllProjects::Container AllProjects::gAudacityProjects;
|
||||||
|
|
||||||
/* Declare Static functions */
|
/* Declare Static functions */
|
||||||
static void SetActiveProject(AudacityProject * project);
|
static void SetActiveProject(AudacityProject * project);
|
||||||
@ -656,15 +702,16 @@ AudacityProject *CreateNewAudacityProject()
|
|||||||
|
|
||||||
// Create and show a NEW project
|
// Create and show a NEW project
|
||||||
// Use a non-default deleter in the smart pointer!
|
// Use a non-default deleter in the smart pointer!
|
||||||
gAudacityProjects.push_back( AProjectHolder {
|
auto sp = AllProjects::value_type {
|
||||||
safenew AudacityProject(
|
safenew AudacityProject(
|
||||||
nullptr, -1,
|
nullptr, -1,
|
||||||
wxDefaultPosition,
|
wxDefaultPosition,
|
||||||
wxSize(wndRect.width, wndRect.height)
|
wxSize(wndRect.width, wndRect.height)
|
||||||
),
|
),
|
||||||
Destroyer< AudacityProject > {}
|
Destroyer< AudacityProject > {}
|
||||||
} );
|
};
|
||||||
const auto p = gAudacityProjects.back().get();
|
AllProjects{}.Add( sp );
|
||||||
|
auto p = sp.get();
|
||||||
auto &project = *p;
|
auto &project = *p;
|
||||||
auto &window = GetProjectFrame( *p );
|
auto &window = GetProjectFrame( *p );
|
||||||
|
|
||||||
@ -697,27 +744,6 @@ AudacityProject *CreateNewAudacityProject()
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedrawAllProjects()
|
|
||||||
{
|
|
||||||
size_t len = gAudacityProjects.size();
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
ProjectWindow::Get( *gAudacityProjects[i] ).RedrawProject();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefreshCursorForAllProjects()
|
|
||||||
{
|
|
||||||
size_t len = gAudacityProjects.size();
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
ProjectWindow::Get( *gAudacityProjects[i] ).RefreshCursor();
|
|
||||||
}
|
|
||||||
|
|
||||||
AUDACITY_DLL_API void CloseAllProjects()
|
|
||||||
{
|
|
||||||
size_t len = gAudacityProjects.size();
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
GetProjectFrame( *gAudacityProjects[i] ).Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// BG: The default size and position of the first window
|
// BG: The default size and position of the first window
|
||||||
void GetDefaultWindowRect(wxRect *defRect)
|
void GetDefaultWindowRect(wxRect *defRect)
|
||||||
{
|
{
|
||||||
@ -861,7 +887,7 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized)
|
|||||||
|
|
||||||
// IF projects empty, THEN it's the first window.
|
// IF projects empty, THEN it's the first window.
|
||||||
// It lands where the config says it should, and can straddle screen.
|
// It lands where the config says it should, and can straddle screen.
|
||||||
if (gAudacityProjects.empty()) {
|
if (AllProjects{}.empty()) {
|
||||||
if (*pMaximized || *pIconized) {
|
if (*pMaximized || *pIconized) {
|
||||||
*nextRect = normalRect;
|
*nextRect = normalRect;
|
||||||
}
|
}
|
||||||
@ -899,12 +925,14 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized)
|
|||||||
|
|
||||||
bool validWindowSize = false;
|
bool validWindowSize = false;
|
||||||
ProjectWindow * validProject = NULL;
|
ProjectWindow * validProject = NULL;
|
||||||
size_t numProjects = gAudacityProjects.size();
|
for ( auto iter = AllProjects{}.rbegin(), end = AllProjects{}.rend();
|
||||||
for (int i = numProjects; i > 0 ; i--) {
|
iter != end; ++iter
|
||||||
if (!GetProjectFrame( *gAudacityProjects[i-1] ).IsIconized()) {
|
) {
|
||||||
validWindowSize = true;
|
auto pProject = *iter;
|
||||||
validProject = &ProjectWindow::Get( *gAudacityProjects[i-1] );
|
if (!GetProjectFrame( *pProject ).IsIconized()) {
|
||||||
break;
|
validWindowSize = true;
|
||||||
|
validProject = &ProjectWindow::Get( *pProject );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (validWindowSize) {
|
if (validWindowSize) {
|
||||||
@ -2122,35 +2150,8 @@ void AudacityProject::HandleResize()
|
|||||||
UpdateLayout();
|
UpdateLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
// How many projects that do not have a name yet?
|
|
||||||
int AudacityProject::CountUnnamed()
|
|
||||||
{
|
|
||||||
int j = 0;
|
|
||||||
for ( size_t i = 0; i < gAudacityProjects.size(); i++) {
|
|
||||||
if ( gAudacityProjects[i] )
|
|
||||||
if ( gAudacityProjects[i]->GetProjectName().empty() )
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudacityProject::RefreshAllTitles(bool bShowProjectNumbers )
|
|
||||||
{
|
|
||||||
for ( size_t i = 0; i < gAudacityProjects.size(); i++) {
|
|
||||||
if ( gAudacityProjects[i] ) {
|
|
||||||
if ( !GetProjectFrame( *gAudacityProjects[i] ).IsIconized() ) {
|
|
||||||
AudacityProject * p;
|
|
||||||
p = gAudacityProjects[i].get();
|
|
||||||
p->SetProjectTitle( bShowProjectNumbers ? p->GetProjectNumber() : -1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudacityProject::OnIconize(wxIconizeEvent &event)
|
void AudacityProject::OnIconize(wxIconizeEvent &event)
|
||||||
{
|
{
|
||||||
int VisibleProjectCount = 0;
|
|
||||||
|
|
||||||
//JKC: On Iconizing we get called twice. Don't know
|
//JKC: On Iconizing we get called twice. Don't know
|
||||||
// why but it does no harm.
|
// why but it does no harm.
|
||||||
// Should we be returning true/false rather than
|
// Should we be returning true/false rather than
|
||||||
@ -2161,12 +2162,12 @@ void AudacityProject::OnIconize(wxIconizeEvent &event)
|
|||||||
|
|
||||||
// VisibileProjectCount seems to be just a counter for debugging.
|
// VisibileProjectCount seems to be just a counter for debugging.
|
||||||
// It's not used outside this function.
|
// It's not used outside this function.
|
||||||
for(i=0;i<gAudacityProjects.size();i++){
|
auto VisibleProjectCount = std::count_if(
|
||||||
if(gAudacityProjects[i]){
|
AllProjects{}.begin(), AllProjects{}.end(),
|
||||||
if( !GetProjectFrame( *gAudacityProjects[i] ).IsIconized() )
|
[]( const AllProjects::value_type &ptr ){
|
||||||
VisibleProjectCount++;
|
return !GetProjectFrame( *ptr ).IsIconized();
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
|
||||||
// This step is to fix part of Bug 2040, where the BackingPanel
|
// This step is to fix part of Bug 2040, where the BackingPanel
|
||||||
@ -2410,8 +2411,17 @@ void AudacityProject::OnMouseEvent(wxMouseEvent & event)
|
|||||||
|
|
||||||
// TitleRestorer restores project window titles to what they were, in its destructor.
|
// TitleRestorer restores project window titles to what they were, in its destructor.
|
||||||
class TitleRestorer{
|
class TitleRestorer{
|
||||||
|
static void RefreshAllTitles(bool bShowProjectNumbers )
|
||||||
|
{
|
||||||
|
for ( auto pProject : AllProjects{} ) {
|
||||||
|
if ( !GetProjectFrame( *pProject ).IsIconized() ) {
|
||||||
|
pProject->SetProjectTitle(
|
||||||
|
bShowProjectNumbers ? pProject->GetProjectNumber() : -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
TitleRestorer(AudacityProject * p ){
|
TitleRestorer(AudacityProject * p ) {
|
||||||
auto &window = GetProjectFrame( *p );
|
auto &window = GetProjectFrame( *p );
|
||||||
if( window.IsIconized() )
|
if( window.IsIconized() )
|
||||||
window.Restore();
|
window.Restore();
|
||||||
@ -2421,10 +2431,15 @@ public:
|
|||||||
sProjName = p->GetProjectName();
|
sProjName = p->GetProjectName();
|
||||||
if (sProjName.empty()){
|
if (sProjName.empty()){
|
||||||
sProjName = _("<untitled>");
|
sProjName = _("<untitled>");
|
||||||
UnnamedCount=AudacityProject::CountUnnamed();
|
UnnamedCount = std::count_if(
|
||||||
|
AllProjects{}.begin(), AllProjects{}.end(),
|
||||||
|
[]( const AllProjects::value_type &ptr ){
|
||||||
|
return ptr->GetProjectName().empty();
|
||||||
|
}
|
||||||
|
);
|
||||||
if( UnnamedCount > 1 ){
|
if( UnnamedCount > 1 ){
|
||||||
sProjNumber.Printf( "[Project %02i] ", p->GetProjectNumber()+1 );
|
sProjNumber.Printf( "[Project %02i] ", p->GetProjectNumber()+1 );
|
||||||
AudacityProject::RefreshAllTitles( true );
|
RefreshAllTitles( true );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UnnamedCount = 0;
|
UnnamedCount = 0;
|
||||||
@ -2432,11 +2447,11 @@ public:
|
|||||||
};
|
};
|
||||||
~TitleRestorer() {
|
~TitleRestorer() {
|
||||||
if( UnnamedCount > 1 )
|
if( UnnamedCount > 1 )
|
||||||
AudacityProject::RefreshAllTitles( false );
|
RefreshAllTitles( false );
|
||||||
};
|
};
|
||||||
wxString sProjNumber;
|
wxString sProjNumber;
|
||||||
wxString sProjName;
|
wxString sProjName;
|
||||||
int UnnamedCount;
|
size_t UnnamedCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2560,7 +2575,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
|||||||
|
|
||||||
// DanH: If we're definitely about to quit, clear the clipboard.
|
// DanH: If we're definitely about to quit, clear the clipboard.
|
||||||
// Doing this after Deref'ing the DirManager causes problems.
|
// Doing this after Deref'ing the DirManager causes problems.
|
||||||
if ((gAudacityProjects.size() == 1) &&
|
if ((AllProjects{}.size() == 1) &&
|
||||||
(quitOnClose || AllProjects::Closing()))
|
(quitOnClose || AllProjects::Closing()))
|
||||||
Clipboard::Get().Clear();
|
Clipboard::Get().Clear();
|
||||||
|
|
||||||
@ -2606,21 +2621,14 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
|||||||
// have been deleted before this.
|
// have been deleted before this.
|
||||||
DirManager::Destroy( project );
|
DirManager::Destroy( project );
|
||||||
|
|
||||||
AProjectHolder pSelf;
|
// Remove self from the global array, but defer destruction of self
|
||||||
{
|
auto pSelf = AllProjects{}.Remove( *this );
|
||||||
ODLocker locker{ &AudacityProject::AllProjectDeleteMutex() };
|
wxASSERT( pSelf );
|
||||||
auto end = gAudacityProjects.end();
|
|
||||||
auto it = std::find_if(gAudacityProjects.begin(), end,
|
|
||||||
[this] (const AProjectHolder &p) { return p.get() == this; });
|
|
||||||
wxASSERT( it != end );
|
|
||||||
pSelf = std::move( *it );
|
|
||||||
gAudacityProjects.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gActiveProject == this) {
|
if (gActiveProject == this) {
|
||||||
// Find a NEW active project
|
// Find a NEW active project
|
||||||
if (gAudacityProjects.size() > 0) {
|
if ( !AllProjects{}.empty() ) {
|
||||||
SetActiveProject(gAudacityProjects[0].get());
|
SetActiveProject(AllProjects{}.begin()->get());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SetActiveProject(NULL);
|
SetActiveProject(NULL);
|
||||||
@ -2633,7 +2641,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
|||||||
gAudioIO->SetListener(gActiveProject);
|
gAudioIO->SetListener(gActiveProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gAudacityProjects.empty() && !AllProjects::Closing()) {
|
if (AllProjects{}.empty() && !AllProjects::Closing()) {
|
||||||
|
|
||||||
#if !defined(__WXMAC__)
|
#if !defined(__WXMAC__)
|
||||||
if (quitOnClose) {
|
if (quitOnClose) {
|
||||||
@ -2773,18 +2781,18 @@ wxArrayString AudacityProject::ShowOpenDialog(const wxString &extraformat, const
|
|||||||
bool AudacityProject::IsAlreadyOpen(const FilePath &projPathName)
|
bool AudacityProject::IsAlreadyOpen(const FilePath &projPathName)
|
||||||
{
|
{
|
||||||
const wxFileName newProjPathName(projPathName);
|
const wxFileName newProjPathName(projPathName);
|
||||||
size_t numProjects = gAudacityProjects.size();
|
auto start = AllProjects{}.begin(), finish = AllProjects{}.end(),
|
||||||
for (size_t i = 0; i < numProjects; i++)
|
iter = std::find_if( start, finish,
|
||||||
{
|
[&]( const AllProjects::value_type &ptr ){
|
||||||
if (newProjPathName.SameAs(gAudacityProjects[i]->mFileName))
|
return (newProjPathName.SameAs(wxFileNameWrapper{ ptr->mFileName }));
|
||||||
{
|
} );
|
||||||
wxString errMsg =
|
if (iter != finish) {
|
||||||
wxString::Format(_("%s is already open in another window."),
|
wxString errMsg =
|
||||||
newProjPathName.GetName());
|
wxString::Format(_("%s is already open in another window."),
|
||||||
wxLogError(errMsg);
|
newProjPathName.GetName());
|
||||||
AudacityMessageBox(errMsg, _("Error Opening Project"), wxOK | wxCENTRE);
|
wxLogError(errMsg);
|
||||||
return true;
|
AudacityMessageBox(errMsg, _("Error Opening Project"), wxOK | wxCENTRE);
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4498,7 +4506,7 @@ For an audio file that will open in other apps, use 'Export'.\n");
|
|||||||
// saved to disk, and we then need to check the destination file is not
|
// saved to disk, and we then need to check the destination file is not
|
||||||
// open in another window.
|
// open in another window.
|
||||||
int mayOverwrite = (mFileName == fName)? 2 : 1;
|
int mayOverwrite = (mFileName == fName)? 2 : 1;
|
||||||
for (auto p : gAudacityProjects) {
|
for ( auto p : AllProjects{} ) {
|
||||||
const wxFileName openProjectName(p->mFileName);
|
const wxFileName openProjectName(p->mFileName);
|
||||||
if (openProjectName.SameAs(fName)) {
|
if (openProjectName.SameAs(fName)) {
|
||||||
mayOverwrite -= 1;
|
mayOverwrite -= 1;
|
||||||
@ -5223,10 +5231,6 @@ void AudacityProject::SetSyncLock(bool flag)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudacityProject::GetOpenProjectCount() {
|
|
||||||
return gAudacityProjects.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudacityProject::IsProjectSaved() {
|
bool AudacityProject::IsProjectSaved() {
|
||||||
auto &project = *this;
|
auto &project = *this;
|
||||||
auto &dirManager = DirManager::Get( project );
|
auto &dirManager = DirManager::Get( project );
|
||||||
|
@ -83,22 +83,13 @@ class WaveClip;
|
|||||||
|
|
||||||
AudacityProject *CreateNewAudacityProject();
|
AudacityProject *CreateNewAudacityProject();
|
||||||
AUDACITY_DLL_API AudacityProject *GetActiveProject();
|
AUDACITY_DLL_API AudacityProject *GetActiveProject();
|
||||||
void RedrawAllProjects();
|
|
||||||
void RefreshCursorForAllProjects();
|
|
||||||
AUDACITY_DLL_API void CloseAllProjects();
|
|
||||||
|
|
||||||
void GetDefaultWindowRect(wxRect *defRect);
|
void GetDefaultWindowRect(wxRect *defRect);
|
||||||
void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized);
|
void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized);
|
||||||
bool IsWindowAccessible(wxRect *requestedRect);
|
bool IsWindowAccessible(wxRect *requestedRect);
|
||||||
|
|
||||||
// Use shared_ptr to projects, because elsewhere we need weak_ptr
|
|
||||||
using AProjectHolder = std::shared_ptr< AudacityProject >;
|
|
||||||
using AProjectArray = std::vector< AProjectHolder >;
|
|
||||||
|
|
||||||
using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
|
using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
|
||||||
|
|
||||||
extern AProjectArray gAudacityProjects;
|
|
||||||
|
|
||||||
|
|
||||||
enum StatusBarField {
|
enum StatusBarField {
|
||||||
stateStatusBarField = 1,
|
stateStatusBarField = 1,
|
||||||
@ -124,9 +115,45 @@ class ImportXMLTagHandler final : public XMLTagHandler
|
|||||||
AudacityProject* mProject;
|
AudacityProject* mProject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief an object of class AllProjects acts like a standard library
|
||||||
|
/// container, but refers to a global array of open projects. So you can
|
||||||
|
/// iterate easily over shared pointers to them with range-for :
|
||||||
|
/// for (auto pProject : AllProjects{}) { ... }
|
||||||
|
/// The pointers are never null.
|
||||||
class AllProjects
|
class AllProjects
|
||||||
{
|
{
|
||||||
|
// Use shared_ptr to projects, because elsewhere we need weak_ptr
|
||||||
|
using AProjectHolder = std::shared_ptr< AudacityProject >;
|
||||||
|
using Container = std::vector< AProjectHolder >;
|
||||||
|
static Container gAudacityProjects;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
AllProjects() = default;
|
||||||
|
|
||||||
|
size_t size() const;
|
||||||
|
bool empty() const { return size() == 0; }
|
||||||
|
|
||||||
|
using const_iterator = Container::const_iterator;
|
||||||
|
const_iterator begin() const;
|
||||||
|
const_iterator end() const;
|
||||||
|
|
||||||
|
using const_reverse_iterator = Container::const_reverse_iterator;
|
||||||
|
const_reverse_iterator rbegin() const;
|
||||||
|
const_reverse_iterator rend() const;
|
||||||
|
|
||||||
|
using value_type = Container::value_type;
|
||||||
|
|
||||||
|
// If the project is present, remove it from the global array and return
|
||||||
|
// a shared pointer, else return null. This invalidates any iterators.
|
||||||
|
value_type Remove( AudacityProject &project );
|
||||||
|
|
||||||
|
// This invalidates iterators
|
||||||
|
void Add( const value_type &pProject );
|
||||||
|
|
||||||
|
/// In case you must iterate in a non-main thread, use this to prevent
|
||||||
|
/// changes in the set of open projects
|
||||||
|
static ODLock &Mutex();
|
||||||
|
|
||||||
// Return true if all projects do close (always so if force == true)
|
// Return true if all projects do close (always so if force == true)
|
||||||
// But if return is false, that means the user cancelled close of at least
|
// But if return is false, that means the user cancelled close of at least
|
||||||
// one un-saved project.
|
// one un-saved project.
|
||||||
@ -310,7 +337,6 @@ public:
|
|||||||
|
|
||||||
// Timer Record Auto Save/Export Routines
|
// Timer Record Auto Save/Export Routines
|
||||||
bool SaveFromTimerRecording(wxFileName fnFile);
|
bool SaveFromTimerRecording(wxFileName fnFile);
|
||||||
static int GetOpenProjectCount();
|
|
||||||
bool IsProjectSaved();
|
bool IsProjectSaved();
|
||||||
void ResetProjectToEmpty();
|
void ResetProjectToEmpty();
|
||||||
void ResetProjectFileIO();
|
void ResetProjectFileIO();
|
||||||
@ -351,8 +377,6 @@ public:
|
|||||||
// Other commands
|
// Other commands
|
||||||
|
|
||||||
int GetProjectNumber(){ return mProjectNo;};
|
int GetProjectNumber(){ return mProjectNo;};
|
||||||
static int CountUnnamed();
|
|
||||||
static void RefreshAllTitles(bool bShowProjectNumbers );
|
|
||||||
void UpdatePrefs() override;
|
void UpdatePrefs() override;
|
||||||
void UpdatePrefsVariables();
|
void UpdatePrefsVariables();
|
||||||
void RedrawProject(const bool bForceWaveTracks = false);
|
void RedrawProject(const bool bForceWaveTracks = false);
|
||||||
@ -510,11 +534,6 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<TrackList> mLastSavedTracks;
|
std::shared_ptr<TrackList> mLastSavedTracks;
|
||||||
|
|
||||||
public:
|
|
||||||
///Prevents DELETE from external thread - for e.g. use of GetActiveProject
|
|
||||||
//shared by all projects
|
|
||||||
static ODLock &AllProjectDeleteMutex();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mDirty{ false };
|
bool mDirty{ false };
|
||||||
|
|
||||||
|
@ -705,7 +705,8 @@ bool NyquistEffect::Process()
|
|||||||
mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'MONTH-NAME)\n"), now.GetMonthName(month));
|
mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'MONTH-NAME)\n"), now.GetMonthName(month));
|
||||||
mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DAY-NAME)\n"), now.GetWeekDayName(day));
|
mProps += wxString::Format(wxT("(putprop '*SYSTEM-TIME* \"%s\" 'DAY-NAME)\n"), now.GetWeekDayName(day));
|
||||||
|
|
||||||
mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'PROJECTS)\n"), (int) gAudacityProjects.size());
|
mProps += wxString::Format(wxT("(putprop '*PROJECT* %d 'PROJECTS)\n"),
|
||||||
|
(int) AllProjects{}.size());
|
||||||
mProps += wxString::Format(wxT("(putprop '*PROJECT* \"%s\" 'NAME)\n"), project->GetProjectName());
|
mProps += wxString::Format(wxT("(putprop '*PROJECT* \"%s\" 'NAME)\n"), project->GetProjectName());
|
||||||
|
|
||||||
int numTracks = 0;
|
int numTracks = 0;
|
||||||
|
@ -676,9 +676,9 @@ bool Exporter::GetFilename()
|
|||||||
// Also, this can only happen for uncompressed audio.
|
// Also, this can only happen for uncompressed audio.
|
||||||
bool overwritingMissingAliasFiles;
|
bool overwritingMissingAliasFiles;
|
||||||
overwritingMissingAliasFiles = false;
|
overwritingMissingAliasFiles = false;
|
||||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
for (auto pProject : AllProjects{}) {
|
||||||
AliasedFileArray aliasedFiles;
|
AliasedFileArray aliasedFiles;
|
||||||
FindDependencies(gAudacityProjects[i].get(), aliasedFiles);
|
FindDependencies(pProject.get(), aliasedFiles);
|
||||||
for (const auto &aliasedFile : aliasedFiles) {
|
for (const auto &aliasedFile : aliasedFiles) {
|
||||||
if (mFilename.GetFullPath() == aliasedFile.mFileName.GetFullPath() &&
|
if (mFilename.GetFullPath() == aliasedFile.mFileName.GetFullPath() &&
|
||||||
!mFilename.FileExists()) {
|
!mFilename.FileExists()) {
|
||||||
|
@ -179,9 +179,7 @@ void DoReloadPreferences( AudacityProject &project )
|
|||||||
// LL: Moved from PrefsDialog since wxWidgets on OSX can't deal with
|
// LL: Moved from PrefsDialog since wxWidgets on OSX can't deal with
|
||||||
// rebuilding the menus while the PrefsDialog is still in the modal
|
// rebuilding the menus while the PrefsDialog is still in the modal
|
||||||
// state.
|
// state.
|
||||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
for (auto p : AllProjects{}) {
|
||||||
AudacityProject *p = gAudacityProjects[i].get();
|
|
||||||
|
|
||||||
MenuManager::Get(*p).RebuildMenuBar(*p);
|
MenuManager::Get(*p).RebuildMenuBar(*p);
|
||||||
// TODO: The comment below suggests this workaround is obsolete.
|
// TODO: The comment below suggests this workaround is obsolete.
|
||||||
#if defined(__WXGTK__)
|
#if defined(__WXGTK__)
|
||||||
@ -1031,9 +1029,7 @@ void OnPreferences(const CommandContext &context)
|
|||||||
// LL: Moved from PrefsDialog since wxWidgets on OSX can't deal with
|
// LL: Moved from PrefsDialog since wxWidgets on OSX can't deal with
|
||||||
// rebuilding the menus while the PrefsDialog is still in the modal
|
// rebuilding the menus while the PrefsDialog is still in the modal
|
||||||
// state.
|
// state.
|
||||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
for (auto p : AllProjects{}) {
|
||||||
AudacityProject *p = gAudacityProjects[i].get();
|
|
||||||
|
|
||||||
MenuManager::Get(*p).RebuildMenuBar(*p);
|
MenuManager::Get(*p).RebuildMenuBar(*p);
|
||||||
// TODO: The comment below suggests this workaround is obsolete.
|
// TODO: The comment below suggests this workaround is obsolete.
|
||||||
#if defined(__WXGTK__)
|
#if defined(__WXGTK__)
|
||||||
|
@ -94,16 +94,14 @@ void DoPlayStop(const CommandContext &context)
|
|||||||
// old and start the NEW.
|
// old and start the NEW.
|
||||||
|
|
||||||
//find out which project we need;
|
//find out which project we need;
|
||||||
AudacityProject* otherProject = NULL;
|
auto start = AllProjects{}.begin(), finish = AllProjects{}.end(),
|
||||||
for(unsigned i=0; i<gAudacityProjects.size(); i++) {
|
iter = std::find_if( start, finish,
|
||||||
if(gAudioIO->IsStreamActive(gAudacityProjects[i]->GetAudioIOToken())) {
|
[]( const AllProjects::value_type &ptr ){
|
||||||
otherProject=gAudacityProjects[i].get();
|
return gAudioIO->IsStreamActive(ptr->GetAudioIOToken()); } );
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//stop playing the other project
|
//stop playing the other project
|
||||||
if(otherProject) {
|
if(iter != finish) {
|
||||||
|
auto otherProject = *iter;
|
||||||
auto &otherToolbar = ControlToolBar::Get( *otherProject );
|
auto &otherToolbar = ControlToolBar::Get( *otherProject );
|
||||||
otherToolbar.SetPlay(false); //Pops
|
otherToolbar.SetPlay(false); //Pops
|
||||||
otherToolbar.SetStop(true); //Pushes stop down
|
otherToolbar.SetStop(true); //Pushes stop down
|
||||||
@ -407,7 +405,7 @@ void OnTimerRecord(const CommandContext &context)
|
|||||||
// MY: Due to improvements in how Timer Recording saves and/or exports
|
// 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
|
// it is now safer to disable Timer Recording when there is more than
|
||||||
// one open project.
|
// one open project.
|
||||||
if (AudacityProject::GetOpenProjectCount() > 1) {
|
if (AllProjects{}.size() > 1) {
|
||||||
AudacityMessageBox(_("Timer Recording cannot be used with more than one open project.\n\nPlease close any additional projects and try again."),
|
AudacityMessageBox(_("Timer Recording cannot be used with more than one open project.\n\nPlease close any additional projects and try again."),
|
||||||
_("Timer Recording"),
|
_("Timer Recording"),
|
||||||
wxICON_INFORMATION | wxOK);
|
wxICON_INFORMATION | wxOK);
|
||||||
|
@ -89,13 +89,13 @@ void OnMacBringAllToFront(const CommandContext &)
|
|||||||
{
|
{
|
||||||
// Reall this de-miniaturizes all, which is not exactly the standard
|
// Reall this de-miniaturizes all, which is not exactly the standard
|
||||||
// behavior.
|
// behavior.
|
||||||
for (const auto project : gAudacityProjects)
|
for (const auto project : AllProjects{})
|
||||||
GetProjectFrame( *project ).Raise();
|
GetProjectFrame( *project ).Raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnMacMinimizeAll(const CommandContext &)
|
void OnMacMinimizeAll(const CommandContext &)
|
||||||
{
|
{
|
||||||
for (const auto project : gAudacityProjects) {
|
for (const auto project : AllProjects{}) {
|
||||||
DoMacMinimize(project.get());
|
DoMacMinimize(project.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,7 +421,7 @@ void ODManager::Start()
|
|||||||
{
|
{
|
||||||
mNeedsDraw=0;
|
mNeedsDraw=0;
|
||||||
wxCommandEvent event( EVT_ODTASK_UPDATE );
|
wxCommandEvent event( EVT_ODTASK_UPDATE );
|
||||||
ODLocker locker{ &AudacityProject::AllProjectDeleteMutex() };
|
ODLocker locker{ &AllProjects::Mutex() };
|
||||||
AudacityProject* proj = GetActiveProject();
|
AudacityProject* proj = GetActiveProject();
|
||||||
if(proj)
|
if(proj)
|
||||||
GetProjectFrame( *proj )
|
GetProjectFrame( *proj )
|
||||||
|
@ -129,13 +129,13 @@ void ODTask::DoSome(float amountWork)
|
|||||||
ODManager::Instance()->AddTask(this);
|
ODManager::Instance()->AddTask(this);
|
||||||
|
|
||||||
//we did a bit of progress - we should allow a resave.
|
//we did a bit of progress - we should allow a resave.
|
||||||
ODLocker locker{ &AudacityProject::AllProjectDeleteMutex() };
|
ODLocker locker{ &AllProjects::Mutex() };
|
||||||
for(unsigned i=0; i<gAudacityProjects.size(); i++)
|
for ( auto pProject : AllProjects{} )
|
||||||
{
|
{
|
||||||
if(IsTaskAssociatedWithProject(gAudacityProjects[i].get()))
|
if(IsTaskAssociatedWithProject(pProject.get()))
|
||||||
{
|
{
|
||||||
//mark the changes so that the project can be resaved.
|
//mark the changes so that the project can be resaved.
|
||||||
UndoManager::Get( *gAudacityProjects[i] ).SetODChangesFlag();
|
UndoManager::Get( *pProject ).SetODChangesFlag();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,16 +153,16 @@ void ODTask::DoSome(float amountWork)
|
|||||||
|
|
||||||
wxCommandEvent event( EVT_ODTASK_COMPLETE );
|
wxCommandEvent event( EVT_ODTASK_COMPLETE );
|
||||||
|
|
||||||
ODLocker locker{ &AudacityProject::AllProjectDeleteMutex() };
|
ODLocker locker{ &AllProjects::Mutex() };
|
||||||
for(unsigned i=0; i<gAudacityProjects.size(); i++)
|
for ( auto pProject : AllProjects{} )
|
||||||
{
|
{
|
||||||
if(IsTaskAssociatedWithProject(gAudacityProjects[i].get()))
|
if(IsTaskAssociatedWithProject(pProject.get()))
|
||||||
{
|
{
|
||||||
//this assumes tasks are only associated with one project.
|
//this assumes tasks are only associated with one project.
|
||||||
GetProjectFrame( *gAudacityProjects[i] )
|
GetProjectFrame( *pProject )
|
||||||
.GetEventHandler()->AddPendingEvent(event);
|
.GetEventHandler()->AddPendingEvent(event);
|
||||||
//mark the changes so that the project can be resaved.
|
//mark the changes so that the project can be resaved.
|
||||||
UndoManager::Get( *gAudacityProjects[i] ).SetODChangesFlag();
|
UndoManager::Get( *pProject ).SetODChangesFlag();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,13 +226,15 @@ void ToolsToolBar::SetCurrentTool(int tool)
|
|||||||
mCurrentTool=tool;
|
mCurrentTool=tool;
|
||||||
mTool[mCurrentTool]->PushDown();
|
mTool[mCurrentTool]->PushDown();
|
||||||
}
|
}
|
||||||
//JKC: ANSWER-ME: Why is this RedrawAllProjects() line required?
|
//JKC: ANSWER-ME: Why is this required?
|
||||||
//msmeyer: I think it isn't, we leave it out for 1.3.1 (beta), and
|
//msmeyer: I think it isn't, we leave it out for 1.3.1 (beta), and
|
||||||
// we'll see if anyone complains.
|
// we'll see if anyone complains.
|
||||||
// RedrawAllProjects();
|
//for ( auto pProject : AllProjects{} )
|
||||||
|
// ProjectWindow::Get( *pProject ).RedrawProject();
|
||||||
|
|
||||||
//msmeyer: But we instruct the projects to handle the cursor shape again
|
//msmeyer: But we instruct the projects to handle the cursor shape again
|
||||||
RefreshCursorForAllProjects();
|
for ( auto pProject : AllProjects{} )
|
||||||
|
ProjectWindow::Get( *pProject ).RefreshCursor();
|
||||||
|
|
||||||
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
||||||
IsDown(multiTool));
|
IsDown(multiTool));
|
||||||
@ -264,7 +266,8 @@ void ToolsToolBar::OnTool(wxCommandEvent & evt)
|
|||||||
else
|
else
|
||||||
mTool[i]->PopUp();
|
mTool[i]->PopUp();
|
||||||
|
|
||||||
RedrawAllProjects();
|
for ( auto pProject : AllProjects{} )
|
||||||
|
ProjectWindow::Get( *pProject ).RedrawProject();
|
||||||
|
|
||||||
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
||||||
IsDown(multiTool));
|
IsDown(multiTool));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user