audacia/src/Project.h

186 lines
6.2 KiB
C++

/**********************************************************************
Audacity: A Digital Audio Editor
Project.h
Dominic Mazzoni
**********************************************************************/
#ifndef __AUDACITY_PROJECT__
#define __AUDACITY_PROJECT__
#include "ClientData.h" // to inherit
#include <memory>
#include <mutex>
#include <wx/weakref.h> // member variable
#include <wx/window.h> // MSVC wants this
class wxFrame;
class wxWindow;
class AudacityProject;
AUDACITY_DLL_API AudacityProject *GetActiveProject();
// For use by ProjectManager only:
AUDACITY_DLL_API void SetActiveProject(AudacityProject * project);
/// \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 AUDACITY_DLL_API 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:
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 std::mutex &Mutex();
// 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;
};
// Container of various objects associated with the project, which is
// responsible for destroying them
using AttachedProjectObjects = ClientData::Site<
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
using AttachedProjectWindows = ClientData::Site<
AudacityProject, wxWindow, ClientData::SkipCopying, ClientData::BarePtr
>;
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACK_PANEL_TIMER, wxCommandEvent);
// 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);
///\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.
class AUDACITY_DLL_API AudacityProject final
: public wxEvtHandler
, public AttachedProjectObjects
, public AttachedProjectWindows
, public std::enable_shared_from_this<AudacityProject>
{
public:
using AttachedObjects = ::AttachedProjectObjects;
using AttachedWindows = ::AttachedProjectWindows;
AudacityProject();
virtual ~AudacityProject();
wxFrame *GetFrame() { return mFrame; }
const wxFrame *GetFrame() const { return mFrame; }
void SetFrame( wxFrame *pFrame );
wxWindow *GetPanel() { return mPanel; }
const wxWindow *GetPanel() const { return mPanel; }
void SetPanel( wxWindow *pPanel );
int GetProjectNumber(){ return mProjectNo;}
// 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);
// 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:
// The project's name
wxString mName;
static int mProjectCounter;// global counter.
int mProjectNo; // count when this project was created.
FilePath mInitialImportPath;
public:
bool mbBusyImporting{ false }; // used to fix bug 584
int mBatchMode{ 0 };// 0 means not, >0 means in batch mode.
private:
wxWeakRef< wxFrame > mFrame{};
wxWeakRef< wxWindow > mPanel{};
};
///\brief Get the top-level window associated with the project (as a wxFrame
/// only, when you do not need to use the subclass ProjectWindow)
AUDACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project );
AUDACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project );
///\brief Get a pointer to the window associated with a project, or null if
/// the given pointer is null.
inline wxFrame *FindProjectFrame( AudacityProject *project ) {
return project ? &GetProjectFrame( *project ) : nullptr;
}
inline const wxFrame *FindProjectFrame( const AudacityProject *project ) {
return project ? &GetProjectFrame( *project ) : nullptr;
}
///\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 );
#endif