mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 15:19:44 +02:00
Duplicate Project in ProjectWindows
Patch imported by Audacity and adapted for Tenacity. Original commit: 6477c9e0a6cb93b781c6c83153f1d036a7cc4c13 Signed-off-by: Panagiotis Vasilopoulos <hello@alwayslivid.com>
This commit is contained in:
parent
bc13febb29
commit
0843918fa0
172
src/ProjectWindows.cpp
Normal file
172
src/ProjectWindows.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Project.cpp
|
||||
|
||||
Dominic Mazzoni
|
||||
Vaughan Johnson
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
|
||||
#include "Project.h"
|
||||
|
||||
#include "widgets/wxWidgetsBasicUI.h"
|
||||
|
||||
#include <wx/display.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/frame.h>
|
||||
|
||||
wxDEFINE_EVENT(EVT_TRACK_PANEL_TIMER, 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
|
||||
{
|
||||
std::lock_guard<std::mutex> guard{ 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 )
|
||||
{
|
||||
if (!pProject) {
|
||||
wxASSERT(false);
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> guard{ Mutex() };
|
||||
gAudacityProjects.push_back( pProject );
|
||||
}
|
||||
|
||||
std::mutex &AllProjects::Mutex()
|
||||
{
|
||||
static std::mutex theMutex;
|
||||
return theMutex;
|
||||
}
|
||||
|
||||
int AudacityProject::mProjectCounter=0;// global counter.
|
||||
|
||||
/* Define Global Variables */
|
||||
//This array holds onto all of the projects currently open
|
||||
AllProjects::Container AllProjects::gAudacityProjects;
|
||||
|
||||
AudacityProject::AudacityProject()
|
||||
{
|
||||
mProjectNo = mProjectCounter++; // Bug 322
|
||||
AttachedObjects::BuildAll();
|
||||
// But not for the attached windows. They get built only on demand, such as
|
||||
// from menu items.
|
||||
}
|
||||
|
||||
AudacityProject::~AudacityProject()
|
||||
{
|
||||
}
|
||||
|
||||
void AudacityProject::SetFrame( wxFrame *pFrame )
|
||||
{
|
||||
mFrame = pFrame;
|
||||
}
|
||||
|
||||
void AudacityProject::SetPanel( wxWindow *pPanel )
|
||||
{
|
||||
mPanel = pPanel;
|
||||
}
|
||||
|
||||
const wxString &AudacityProject::GetProjectName() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
void AudacityProject::SetProjectName(const wxString &name)
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
FilePath AudacityProject::GetInitialImportPath() const
|
||||
{
|
||||
return mInitialImportPath;
|
||||
}
|
||||
|
||||
void AudacityProject::SetInitialImportPath(const FilePath &path)
|
||||
{
|
||||
if (mInitialImportPath.empty())
|
||||
{
|
||||
mInitialImportPath = path;
|
||||
}
|
||||
}
|
||||
|
||||
TENACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project )
|
||||
{
|
||||
auto ptr = project.GetFrame();
|
||||
if ( !ptr )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
TENACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project )
|
||||
{
|
||||
auto ptr = project.GetFrame();
|
||||
if ( !ptr )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<const BasicUI::WindowPlacement>
|
||||
ProjectFramePlacement( AudacityProject *project )
|
||||
{
|
||||
if (!project)
|
||||
return std::make_unique<BasicUI::WindowPlacement>();
|
||||
return std::make_unique<wxWidgetsWindowPlacement>(
|
||||
&GetProjectFrame(*project));
|
||||
}
|
||||
|
||||
TENACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project )
|
||||
{
|
||||
auto ptr = project.GetPanel();
|
||||
if ( !ptr )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
TENACITY_DLL_API const wxWindow &GetProjectPanel(
|
||||
const AudacityProject &project )
|
||||
{
|
||||
auto ptr = project.GetPanel();
|
||||
if ( !ptr )
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
// Generate the needed, linkable registry functions
|
||||
DEFINE_XML_METHOD_REGISTRY( ProjectFileIORegistry );
|
187
src/ProjectWindows.h
Normal file
187
src/ProjectWindows.h
Normal file
@ -0,0 +1,187 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
Project.h
|
||||
|
||||
Dominic Mazzoni
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_PROJECT__
|
||||
#define __AUDACITY_PROJECT__
|
||||
|
||||
#include "Identifier.h"
|
||||
|
||||
#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;
|
||||
namespace BasicUI { class WindowPlacement; }
|
||||
|
||||
class AudacityProject;
|
||||
|
||||
//! Like a standard library container of all open projects.
|
||||
//! @invariant pointers accessible through the iterators are not null
|
||||
/*!
|
||||
So you can iterate easily over shared pointers to them with range-for :
|
||||
for (auto pProject : AllProjects{}) { ... }
|
||||
The pointers are never null.
|
||||
|
||||
However iterators will be invalid if addition or deletion of projects occur
|
||||
during traversal.
|
||||
*/
|
||||
class TENACITY_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
|
||||
/*!
|
||||
@pre pProject is not null
|
||||
*/
|
||||
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();
|
||||
};
|
||||
|
||||
// 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(TENACITY_DLL_API,
|
||||
EVT_TRACK_PANEL_TIMER, 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 TENACITY_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)
|
||||
TENACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project );
|
||||
TENACITY_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;
|
||||
}
|
||||
|
||||
//! Make a WindowPlacement object suitable for `project` (which may be null)
|
||||
/*! @post return value is not null */
|
||||
TENACITY_DLL_API std::unique_ptr<const BasicUI::WindowPlacement>
|
||||
ProjectFramePlacement( AudacityProject *project );
|
||||
|
||||
///\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)
|
||||
TENACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project );
|
||||
TENACITY_DLL_API const wxWindow &GetProjectPanel(
|
||||
const AudacityProject &project );
|
||||
|
||||
// Generate a registry for serialized data attached to the project
|
||||
#include "XMLMethodRegistry.h"
|
||||
class AudacityProject;
|
||||
using ProjectFileIORegistry = XMLMethodRegistry<AudacityProject>;
|
||||
DECLARE_XML_METHOD_REGISTRY( TENACITY_DLL_API, ProjectFileIORegistry );
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user