2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
Project.h
|
|
|
|
|
|
|
|
Dominic Mazzoni
|
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifndef __AUDACITY_PROJECT__
|
|
|
|
#define __AUDACITY_PROJECT__
|
|
|
|
|
2021-05-23 08:56:30 +00:00
|
|
|
#include "Identifier.h"
|
2018-11-11 02:40:37 +00:00
|
|
|
|
2019-05-29 16:05:22 +00:00
|
|
|
#include "ClientData.h" // to inherit
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-01-24 01:53:37 +00:00
|
|
|
#include <memory>
|
2020-07-07 20:22:31 +00:00
|
|
|
#include <mutex>
|
2019-05-29 16:05:22 +00:00
|
|
|
#include <wx/weakref.h> // member variable
|
2020-05-26 20:20:10 +00:00
|
|
|
#include <wx/window.h> // MSVC wants this
|
2019-05-28 02:27:00 +00:00
|
|
|
|
2019-05-29 16:05:22 +00:00
|
|
|
class wxFrame;
|
2010-01-23 19:44:49 +00:00
|
|
|
class wxWindow;
|
|
|
|
|
2010-07-21 04:53:38 +00:00
|
|
|
class AudacityProject;
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
AUDACITY_DLL_API AudacityProject *GetActiveProject();
|
2019-05-29 15:42:31 +00:00
|
|
|
// For use by ProjectManager only:
|
2020-09-28 12:50:18 +00:00
|
|
|
AUDACITY_DLL_API void SetActiveProject(AudacityProject * project);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2019-05-29 18:19:01 +00:00
|
|
|
/// \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.
|
2020-09-28 12:50:18 +00:00
|
|
|
class AUDACITY_DLL_API AllProjects
|
2019-04-26 03:59:42 +00:00
|
|
|
{
|
2019-05-29 18:19:01 +00:00
|
|
|
// 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;
|
|
|
|
|
2019-04-26 03:59:42 +00:00
|
|
|
public:
|
2019-05-29 18:19:01 +00:00
|
|
|
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 );
|
|
|
|
|
2020-07-07 20:22:31 +00:00
|
|
|
/// In case you must iterate in a non-main thread, use this to prevent
|
|
|
|
/// changes in the set of open projects
|
|
|
|
static std::mutex &Mutex();
|
|
|
|
|
2019-04-26 03:59:42 +00:00
|
|
|
// 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
|
|
|
|
// one un-saved project.
|
|
|
|
static bool Close( bool force = false );
|
|
|
|
|
|
|
|
static bool Closing() { return sbClosing; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
static bool sbClosing;
|
|
|
|
};
|
|
|
|
|
2019-05-28 19:12:31 +00:00
|
|
|
// Container of various objects associated with the project, which is
|
|
|
|
// responsible for destroying them
|
2020-08-25 18:31:06 +00:00
|
|
|
using AttachedProjectObjects = ClientData::Site<
|
2019-05-28 19:12:31 +00:00
|
|
|
AudacityProject, ClientData::Base, ClientData::SkipCopying, std::shared_ptr
|
|
|
|
>;
|
|
|
|
// Container of pointers to various windows associated with the project, which
|
|
|
|
// is not responsible for destroying them -- wxWidgets handles that instead
|
2020-08-25 18:31:06 +00:00
|
|
|
using AttachedProjectWindows = ClientData::Site<
|
Bug 2228: crash closing, only Linux, gcc, opt, wxWidgets 3.0...
... Not the most satisfactory fix, but in fact no dangling pointers will
happen with the code we have now, because the relevant windows are all destroyed
only at the end of AudacityProject's lifetime, including the non-modal windows
(macros, history, lyrics, mixer board, plot spectrum, and contrast) which
are hidden and shown again, not destroyed and recreated, when dismissed and
reopened.
To do: figure out how to make wxWeakRef work on that combination without
crashing.
2019-10-15 22:38:41 +00:00
|
|
|
AudacityProject, wxWindow, ClientData::SkipCopying, ClientData::BarePtr
|
2019-05-28 19:12:31 +00:00
|
|
|
>;
|
2015-04-10 00:20:51 +00:00
|
|
|
|
2019-06-04 05:03:57 +00:00
|
|
|
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
|
|
|
EVT_TRACK_PANEL_TIMER, wxCommandEvent);
|
|
|
|
|
2020-04-21 17:07:01 +00:00
|
|
|
// This event is emitted by the application object when there is a change
|
|
|
|
// in the activated project
|
|
|
|
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
|
|
|
EVT_PROJECT_ACTIVATION, wxCommandEvent);
|
|
|
|
|
2019-05-29 16:05:22 +00:00
|
|
|
///\brief The top-level handle to an Audacity project. It serves as a source
|
|
|
|
/// of events that other objects can bind to, and a container of associated
|
|
|
|
/// sub-objects that it treats opaquely. It stores a filename and a status
|
|
|
|
/// message and a few other things.
|
|
|
|
/// There is very little in this class, most of the intelligence residing in
|
|
|
|
/// the cooperating attached objects.
|
2019-05-28 19:12:31 +00:00
|
|
|
class AUDACITY_DLL_API AudacityProject final
|
|
|
|
: public wxEvtHandler
|
2020-08-25 18:31:06 +00:00
|
|
|
, public AttachedProjectObjects
|
|
|
|
, public AttachedProjectWindows
|
2020-07-01 22:16:39 +00:00
|
|
|
, public std::enable_shared_from_this<AudacityProject>
|
2019-05-28 19:12:31 +00:00
|
|
|
{
|
|
|
|
public:
|
2020-08-25 18:31:06 +00:00
|
|
|
using AttachedObjects = ::AttachedProjectObjects;
|
|
|
|
using AttachedWindows = ::AttachedProjectWindows;
|
2016-05-04 02:30:13 +00:00
|
|
|
|
2019-05-28 19:12:31 +00:00
|
|
|
AudacityProject();
|
|
|
|
virtual ~AudacityProject();
|
2016-05-17 16:19:58 +00:00
|
|
|
|
2019-05-28 19:12:31 +00:00
|
|
|
wxFrame *GetFrame() { return mFrame; }
|
|
|
|
const wxFrame *GetFrame() const { return mFrame; }
|
2019-05-29 16:05:22 +00:00
|
|
|
void SetFrame( wxFrame *pFrame );
|
2019-05-28 19:12:31 +00:00
|
|
|
|
2019-07-03 17:51:53 +00:00
|
|
|
wxWindow *GetPanel() { return mPanel; }
|
|
|
|
const wxWindow *GetPanel() const { return mPanel; }
|
|
|
|
void SetPanel( wxWindow *pPanel );
|
|
|
|
|
2020-07-01 05:45:17 +00:00
|
|
|
int GetProjectNumber(){ return mProjectNo;}
|
2016-05-04 02:30:13 +00:00
|
|
|
|
2020-07-01 05:45:17 +00:00
|
|
|
// Project name can be either empty or have the name of the project.
|
|
|
|
//
|
|
|
|
// If empty, it signifies that the project is empty/unmodified or
|
|
|
|
// that the project hasn't yet been saved to a permanent project
|
|
|
|
// file.
|
|
|
|
//
|
|
|
|
// If a name has been assigned, it is merely used to identify
|
|
|
|
// the project and should not be used for any other purposes.
|
|
|
|
const wxString &GetProjectName() const;
|
|
|
|
void SetProjectName(const wxString &name);
|
2017-08-19 15:35:54 +00:00
|
|
|
|
2020-08-10 22:48:59 +00:00
|
|
|
// Used exclusively in batch mode, this allows commands to remember
|
|
|
|
// and use the initial import path
|
|
|
|
FilePath GetInitialImportPath() const;
|
|
|
|
void SetInitialImportPath(const FilePath &path);
|
|
|
|
|
|
|
|
private:
|
2019-05-28 19:12:31 +00:00
|
|
|
|
2020-07-01 05:45:17 +00:00
|
|
|
// The project's name
|
|
|
|
wxString mName;
|
2019-05-28 19:12:31 +00:00
|
|
|
|
|
|
|
static int mProjectCounter;// global counter.
|
|
|
|
int mProjectNo; // count when this project was created.
|
|
|
|
|
2020-08-10 22:48:59 +00:00
|
|
|
FilePath mInitialImportPath;
|
|
|
|
|
2019-05-28 19:12:31 +00:00
|
|
|
public:
|
|
|
|
bool mbBusyImporting{ false }; // used to fix bug 584
|
|
|
|
int mBatchMode{ 0 };// 0 means not, >0 means in batch mode.
|
|
|
|
|
|
|
|
private:
|
|
|
|
wxWeakRef< wxFrame > mFrame{};
|
2019-07-03 17:51:53 +00:00
|
|
|
wxWeakRef< wxWindow > mPanel{};
|
2019-04-29 06:22:08 +00:00
|
|
|
};
|
|
|
|
|
2019-05-29 16:05:22 +00:00
|
|
|
///\brief Get the top-level window associated with the project (as a wxFrame
|
|
|
|
/// only, when you do not need to use the subclass ProjectWindow)
|
2019-06-08 19:01:56 +00:00
|
|
|
AUDACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project );
|
|
|
|
AUDACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project );
|
2019-05-28 19:12:31 +00:00
|
|
|
|
2019-06-08 19:00:24 +00:00
|
|
|
///\brief Get a pointer to the window associated with a project, or null if
|
2019-05-29 16:05:22 +00:00
|
|
|
/// the given pointer is null.
|
2019-05-28 17:12:56 +00:00
|
|
|
inline wxFrame *FindProjectFrame( AudacityProject *project ) {
|
|
|
|
return project ? &GetProjectFrame( *project ) : nullptr;
|
|
|
|
}
|
|
|
|
inline const wxFrame *FindProjectFrame( const AudacityProject *project ) {
|
|
|
|
return project ? &GetProjectFrame( *project ) : nullptr;
|
|
|
|
}
|
|
|
|
|
2019-07-03 17:51:53 +00:00
|
|
|
///\brief Get the main sub-window of the project frame that displays track data
|
|
|
|
// (as a wxWindow only, when you do not need to use the subclass TrackPanel)
|
|
|
|
AUDACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project );
|
|
|
|
AUDACITY_DLL_API const wxWindow &GetProjectPanel(
|
|
|
|
const AudacityProject &project );
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
#endif
|