Skip to content
This repository was archived by the owner on Dec 18, 2022. It is now read-only.

Commit 03535e7

Browse files
Paul-Licamelin0toose
authored andcommitted
Duplicate Project in ProjectWindows
Patch imported by Audacity and adapted for Tenacity. Original commit: 6477c9e0a6cb93b781c6c83153f1d036a7cc4c13 Signed-off-by: Panagiotis Vasilopoulos <[email protected]>
1 parent 132de00 commit 03535e7

File tree

2 files changed

+359
-0
lines changed

2 files changed

+359
-0
lines changed

src/ProjectWindows.cpp

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/**********************************************************************
2+
3+
Audacity: A Digital Audio Editor
4+
5+
Project.cpp
6+
7+
Dominic Mazzoni
8+
Vaughan Johnson
9+
10+
*//*******************************************************************/
11+
12+
13+
#include "Project.h"
14+
15+
#include "widgets/wxWidgetsBasicUI.h"
16+
17+
#include <wx/display.h>
18+
#include <wx/filename.h>
19+
#include <wx/frame.h>
20+
21+
wxDEFINE_EVENT(EVT_TRACK_PANEL_TIMER, wxCommandEvent);
22+
23+
size_t AllProjects::size() const
24+
{
25+
return gAudacityProjects.size();
26+
}
27+
28+
auto AllProjects::begin() const -> const_iterator
29+
{
30+
return gAudacityProjects.begin();
31+
}
32+
33+
auto AllProjects::end() const -> const_iterator
34+
{
35+
return gAudacityProjects.end();
36+
}
37+
38+
auto AllProjects::rbegin() const -> const_reverse_iterator
39+
{
40+
return gAudacityProjects.rbegin();
41+
}
42+
43+
auto AllProjects::rend() const -> const_reverse_iterator
44+
{
45+
return gAudacityProjects.rend();
46+
}
47+
48+
auto AllProjects::Remove( AudacityProject &project ) -> value_type
49+
{
50+
std::lock_guard<std::mutex> guard{ Mutex() };
51+
auto start = begin(), finish = end(), iter = std::find_if(
52+
start, finish,
53+
[&]( const value_type &ptr ){ return ptr.get() == &project; }
54+
);
55+
if (iter == finish)
56+
return nullptr;
57+
auto result = *iter;
58+
gAudacityProjects.erase( iter );
59+
return result;
60+
}
61+
62+
void AllProjects::Add( const value_type &pProject )
63+
{
64+
if (!pProject) {
65+
wxASSERT(false);
66+
return;
67+
}
68+
std::lock_guard<std::mutex> guard{ Mutex() };
69+
gAudacityProjects.push_back( pProject );
70+
}
71+
72+
std::mutex &AllProjects::Mutex()
73+
{
74+
static std::mutex theMutex;
75+
return theMutex;
76+
}
77+
78+
int AudacityProject::mProjectCounter=0;// global counter.
79+
80+
/* Define Global Variables */
81+
//This array holds onto all of the projects currently open
82+
AllProjects::Container AllProjects::gAudacityProjects;
83+
84+
AudacityProject::AudacityProject()
85+
{
86+
mProjectNo = mProjectCounter++; // Bug 322
87+
AttachedObjects::BuildAll();
88+
// But not for the attached windows. They get built only on demand, such as
89+
// from menu items.
90+
}
91+
92+
AudacityProject::~AudacityProject()
93+
{
94+
}
95+
96+
void AudacityProject::SetFrame( wxFrame *pFrame )
97+
{
98+
mFrame = pFrame;
99+
}
100+
101+
void AudacityProject::SetPanel( wxWindow *pPanel )
102+
{
103+
mPanel = pPanel;
104+
}
105+
106+
const wxString &AudacityProject::GetProjectName() const
107+
{
108+
return mName;
109+
}
110+
111+
void AudacityProject::SetProjectName(const wxString &name)
112+
{
113+
mName = name;
114+
}
115+
116+
FilePath AudacityProject::GetInitialImportPath() const
117+
{
118+
return mInitialImportPath;
119+
}
120+
121+
void AudacityProject::SetInitialImportPath(const FilePath &path)
122+
{
123+
if (mInitialImportPath.empty())
124+
{
125+
mInitialImportPath = path;
126+
}
127+
}
128+
129+
TENACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project )
130+
{
131+
auto ptr = project.GetFrame();
132+
if ( !ptr )
133+
THROW_INCONSISTENCY_EXCEPTION;
134+
return *ptr;
135+
}
136+
137+
TENACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project )
138+
{
139+
auto ptr = project.GetFrame();
140+
if ( !ptr )
141+
THROW_INCONSISTENCY_EXCEPTION;
142+
return *ptr;
143+
}
144+
145+
std::unique_ptr<const BasicUI::WindowPlacement>
146+
ProjectFramePlacement( AudacityProject *project )
147+
{
148+
if (!project)
149+
return std::make_unique<BasicUI::WindowPlacement>();
150+
return std::make_unique<wxWidgetsWindowPlacement>(
151+
&GetProjectFrame(*project));
152+
}
153+
154+
TENACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project )
155+
{
156+
auto ptr = project.GetPanel();
157+
if ( !ptr )
158+
THROW_INCONSISTENCY_EXCEPTION;
159+
return *ptr;
160+
}
161+
162+
TENACITY_DLL_API const wxWindow &GetProjectPanel(
163+
const AudacityProject &project )
164+
{
165+
auto ptr = project.GetPanel();
166+
if ( !ptr )
167+
THROW_INCONSISTENCY_EXCEPTION;
168+
return *ptr;
169+
}
170+
171+
// Generate the needed, linkable registry functions
172+
DEFINE_XML_METHOD_REGISTRY( ProjectFileIORegistry );

src/ProjectWindows.h

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**********************************************************************
2+
3+
Audacity: A Digital Audio Editor
4+
5+
Project.h
6+
7+
Dominic Mazzoni
8+
9+
**********************************************************************/
10+
11+
#ifndef __AUDACITY_PROJECT__
12+
#define __AUDACITY_PROJECT__
13+
14+
#include "Identifier.h"
15+
16+
#include "ClientData.h" // to inherit
17+
18+
#include <memory>
19+
#include <mutex>
20+
#include <wx/weakref.h> // member variable
21+
#include <wx/window.h> // MSVC wants this
22+
23+
class wxFrame;
24+
class wxWindow;
25+
namespace BasicUI { class WindowPlacement; }
26+
27+
class AudacityProject;
28+
29+
//! Like a standard library container of all open projects.
30+
//! @invariant pointers accessible through the iterators are not null
31+
/*!
32+
So you can iterate easily over shared pointers to them with range-for :
33+
for (auto pProject : AllProjects{}) { ... }
34+
The pointers are never null.
35+
36+
However iterators will be invalid if addition or deletion of projects occur
37+
during traversal.
38+
*/
39+
class AUDACITY_DLL_API AllProjects
40+
{
41+
42+
// Use shared_ptr to projects, because elsewhere we need weak_ptr
43+
using AProjectHolder = std::shared_ptr< AudacityProject >;
44+
using Container = std::vector< AProjectHolder >;
45+
static Container gAudacityProjects;
46+
47+
public:
48+
AllProjects() = default;
49+
50+
size_t size() const;
51+
bool empty() const { return size() == 0; }
52+
53+
using const_iterator = Container::const_iterator;
54+
const_iterator begin() const;
55+
const_iterator end() const;
56+
57+
using const_reverse_iterator = Container::const_reverse_iterator;
58+
const_reverse_iterator rbegin() const;
59+
const_reverse_iterator rend() const;
60+
61+
using value_type = Container::value_type;
62+
63+
// If the project is present, remove it from the global array and return
64+
// a shared pointer, else return null. This invalidates any iterators.
65+
value_type Remove( AudacityProject &project );
66+
67+
//! This invalidates iterators
68+
/*!
69+
@pre pProject is not null
70+
*/
71+
void Add( const value_type &pProject );
72+
73+
/// In case you must iterate in a non-main thread, use this to prevent
74+
/// changes in the set of open projects
75+
static std::mutex &Mutex();
76+
};
77+
78+
// Container of various objects associated with the project, which is
79+
// responsible for destroying them
80+
using AttachedProjectObjects = ClientData::Site<
81+
AudacityProject, ClientData::Base, ClientData::SkipCopying, std::shared_ptr
82+
>;
83+
// Container of pointers to various windows associated with the project, which
84+
// is not responsible for destroying them -- wxWidgets handles that instead
85+
using AttachedProjectWindows = ClientData::Site<
86+
AudacityProject, wxWindow, ClientData::SkipCopying, ClientData::BarePtr
87+
>;
88+
89+
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
90+
EVT_TRACK_PANEL_TIMER, wxCommandEvent);
91+
92+
///\brief The top-level handle to an Audacity project. It serves as a source
93+
/// of events that other objects can bind to, and a container of associated
94+
/// sub-objects that it treats opaquely. It stores a filename and a status
95+
/// message and a few other things.
96+
/// There is very little in this class, most of the intelligence residing in
97+
/// the cooperating attached objects.
98+
class AUDACITY_DLL_API AudacityProject final
99+
: public wxEvtHandler
100+
, public AttachedProjectObjects
101+
, public AttachedProjectWindows
102+
, public std::enable_shared_from_this<AudacityProject>
103+
{
104+
public:
105+
using AttachedObjects = ::AttachedProjectObjects;
106+
using AttachedWindows = ::AttachedProjectWindows;
107+
108+
AudacityProject();
109+
virtual ~AudacityProject();
110+
111+
wxFrame *GetFrame() { return mFrame; }
112+
const wxFrame *GetFrame() const { return mFrame; }
113+
void SetFrame( wxFrame *pFrame );
114+
115+
wxWindow *GetPanel() { return mPanel; }
116+
const wxWindow *GetPanel() const { return mPanel; }
117+
void SetPanel( wxWindow *pPanel );
118+
119+
int GetProjectNumber(){ return mProjectNo;}
120+
121+
// Project name can be either empty or have the name of the project.
122+
//
123+
// If empty, it signifies that the project is empty/unmodified or
124+
// that the project hasn't yet been saved to a permanent project
125+
// file.
126+
//
127+
// If a name has been assigned, it is merely used to identify
128+
// the project and should not be used for any other purposes.
129+
const wxString &GetProjectName() const;
130+
void SetProjectName(const wxString &name);
131+
132+
// Used exclusively in batch mode, this allows commands to remember
133+
// and use the initial import path
134+
FilePath GetInitialImportPath() const;
135+
void SetInitialImportPath(const FilePath &path);
136+
137+
private:
138+
139+
// The project's name
140+
wxString mName;
141+
142+
static int mProjectCounter;// global counter.
143+
int mProjectNo; // count when this project was created.
144+
145+
FilePath mInitialImportPath;
146+
147+
public:
148+
bool mbBusyImporting{ false }; // used to fix bug 584
149+
int mBatchMode{ 0 };// 0 means not, >0 means in batch mode.
150+
151+
private:
152+
wxWeakRef< wxFrame > mFrame{};
153+
wxWeakRef< wxWindow > mPanel{};
154+
};
155+
156+
///\brief Get the top-level window associated with the project (as a wxFrame
157+
/// only, when you do not need to use the subclass ProjectWindow)
158+
AUDACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project );
159+
AUDACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project );
160+
161+
///\brief Get a pointer to the window associated with a project, or null if
162+
/// the given pointer is null.
163+
inline wxFrame *FindProjectFrame( AudacityProject *project ) {
164+
return project ? &GetProjectFrame( *project ) : nullptr;
165+
}
166+
inline const wxFrame *FindProjectFrame( const AudacityProject *project ) {
167+
return project ? &GetProjectFrame( *project ) : nullptr;
168+
}
169+
170+
//! Make a WindowPlacement object suitable for `project` (which may be null)
171+
/*! @post return value is not null */
172+
AUDACITY_DLL_API std::unique_ptr<const BasicUI::WindowPlacement>
173+
ProjectFramePlacement( AudacityProject *project );
174+
175+
///\brief Get the main sub-window of the project frame that displays track data
176+
// (as a wxWindow only, when you do not need to use the subclass TrackPanel)
177+
AUDACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project );
178+
AUDACITY_DLL_API const wxWindow &GetProjectPanel(
179+
const AudacityProject &project );
180+
181+
// Generate a registry for serialized data attached to the project
182+
#include "XMLMethodRegistry.h"
183+
class AudacityProject;
184+
using ProjectFileIORegistry = XMLMethodRegistry<AudacityProject>;
185+
DECLARE_XML_METHOD_REGISTRY( AUDACITY_DLL_API, ProjectFileIORegistry );
186+
187+
#endif

0 commit comments

Comments
 (0)