From 338d7cd1646c48903ca2a585cb02b50c6cce6b7a Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Thu, 25 Apr 2019 16:49:31 -0400 Subject: [PATCH] A class encapsulating the global clipboard --- locale/POTFILES.in | 2 + mac/Audacity.xcodeproj/project.pbxproj | 6 ++ src/AudacityApp.cpp | 5 +- src/AudacityApp.h | 5 -- src/Clipboard.cpp | 56 ++++++++++++ src/Clipboard.h | 56 ++++++++++++ src/DirManager.cpp | 11 ++- src/HistoryWindow.cpp | 8 +- src/Makefile.am | 2 + src/Makefile.in | 85 +++++++++++-------- src/Menus.cpp | 3 +- src/Project.cpp | 35 +------- src/Project.h | 12 +-- src/UndoManager.cpp | 3 +- src/menus/EditMenus.cpp | 78 ++++++++--------- src/menus/LabelMenus.cpp | 29 +++---- win/Projects/Audacity/Audacity.vcxproj | 4 +- .../Audacity/Audacity.vcxproj.filters | 8 +- 18 files changed, 248 insertions(+), 160 deletions(-) create mode 100644 src/Clipboard.cpp create mode 100644 src/Clipboard.h diff --git a/locale/POTFILES.in b/locale/POTFILES.in index f87c28273..c9fa34f0c 100644 --- a/locale/POTFILES.in +++ b/locale/POTFILES.in @@ -56,6 +56,8 @@ src/BlockFile.cpp src/BlockFile.h src/CellularPanel.cpp src/CellularPanel.h +src/Clipboard.cpp +src/Clipboard.h src/ClassicThemeAsCeeCode.h src/CrossFade.cpp src/CrossFade.h diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index a2b997ca8..444f3f8bd 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -1290,6 +1290,7 @@ 5EF3E65F203FDFE9006C6882 /* SetEnvelopeCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF3E65D203FDFE9006C6882 /* SetEnvelopeCommand.cpp */; }; 5EF3E662203FE73C006C6882 /* DragCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF3E660203FE73C006C6882 /* DragCommand.cpp */; }; 5EF958851DEB121800191280 /* InconsistencyException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EF958831DEB121800191280 /* InconsistencyException.cpp */; }; + 5EFEAD9E22723E390077DFF6 /* Clipboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EFEAD9C22723E390077DFF6 /* Clipboard.cpp */; }; 65326EC72253D70900844F28 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 65326EAA2253D70900844F28 /* common.c */; }; 65326EC82253D70900844F28 /* common.h in Headers */ = {isa = PBXBuildFile; fileRef = 65326EAB2253D70900844F28 /* common.h */; }; 65326EC92253D70900844F28 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 65326EAC2253D70900844F28 /* config.h */; }; @@ -3318,6 +3319,8 @@ 5EF3E661203FE73C006C6882 /* DragCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragCommand.h; sourceTree = ""; }; 5EF958831DEB121800191280 /* InconsistencyException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InconsistencyException.cpp; sourceTree = ""; }; 5EF958841DEB121800191280 /* InconsistencyException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InconsistencyException.h; sourceTree = ""; }; + 5EFEAD9C22723E390077DFF6 /* Clipboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Clipboard.cpp; sourceTree = ""; }; + 5EFEAD9D22723E390077DFF6 /* Clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clipboard.h; sourceTree = ""; }; 65326E9E2253D2BE00844F28 /* libmp3lame.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmp3lame.a; sourceTree = BUILT_PRODUCTS_DIR; }; 65326EA72253D68900844F28 /* libmpg123.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmpg123.a; sourceTree = BUILT_PRODUCTS_DIR; }; 65326EA92253D70900844F28 /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS; sourceTree = ""; }; @@ -4285,6 +4288,7 @@ 1790AFDA09883BFD008A330A /* Benchmark.cpp */, 1790AFE809883BFD008A330A /* BlockFile.cpp */, 5E0A1CDB20E95FF7001AAF8D /* CellularPanel.cpp */, + 5EFEAD9C22723E390077DFF6 /* Clipboard.cpp */, 1790AFF409883BFD008A330A /* CrossFade.cpp */, 2849B4600A7444BE00ECF12D /* Dependencies.cpp */, 28D000A31A32920C00367B21 /* DeviceChange.cpp */, @@ -4381,6 +4385,7 @@ 1790AFE909883BFD008A330A /* BlockFile.h */, 5E0A1CDC20E95FF7001AAF8D /* CellularPanel.h */, 5E60AC79214C31B100A82791 /* ClassicThemeAsCeeCode.h */, + 5EFEAD9D22723E390077DFF6 /* Clipboard.h */, 1790AFF009883BFD008A330A /* configtemplate.h */, 1790AFF509883BFD008A330A /* CrossFade.h */, 5E60AC7A214C31B100A82791 /* DarkThemeAsCeeCode.h */, @@ -8594,6 +8599,7 @@ 5E19D655217D51190024D0B1 /* PluginMenus.cpp in Sources */, EDFCEBB518894B9E00C98E51 /* Equalization48x.cpp in Sources */, 2801127B1943EE0E00D98A16 /* HelpSystem.cpp in Sources */, + 5EFEAD9E22723E390077DFF6 /* Clipboard.cpp in Sources */, 28F67179197DFA1C00075C32 /* FormatClassifier.cpp in Sources */, 28F6717A197DFA1C00075C32 /* MultiFormatReader.cpp in Sources */, 28F6717B197DFA1C00075C32 /* SpecPowerMeter.cpp in Sources */, diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 2199f55d1..4216f4a47 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -73,6 +73,7 @@ It handles initialization and termination by subclassing wxApp. #include "AColor.h" #include "AudioIO.h" #include "Benchmark.h" +#include "Clipboard.h" #include "DirManager.h" #include "commands/CommandHandler.h" #include "commands/AppCommandEvent.h" @@ -244,8 +245,6 @@ It handles initialization and termination by subclassing wxApp. /// Custom events //////////////////////////////////////////////////////////// -wxDEFINE_EVENT( EVT_CLIPBOARD_CHANGE, wxCommandEvent); - DEFINE_EVENT_TYPE(EVT_OPEN_AUDIO_FILE); wxDEFINE_EVENT(EVT_LANGUAGE_CHANGE, wxCommandEvent); @@ -290,7 +289,7 @@ void QuitAudacity(bool bForce) if (gAudacityProjects.empty()) { #ifdef __WXMAC__ - AudacityProject::DeleteClipboard(); + Clipboard::Get().Clear(); #endif } else diff --git a/src/AudacityApp.h b/src/AudacityApp.h index 7dc1cec36..0060983ba 100644 --- a/src/AudacityApp.h +++ b/src/AudacityApp.h @@ -48,11 +48,6 @@ void QuitAudacity(); extern bool gIsQuitting; -// An event emitted by the application whenever the global clipboard's -// contents change. -wxDECLARE_EXPORTED_EVENT( AUDACITY_DLL_API, - EVT_CLIPBOARD_CHANGE, wxCommandEvent); - // Asynchronous open DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_OPEN_AUDIO_FILE, -1); diff --git a/src/Clipboard.cpp b/src/Clipboard.cpp new file mode 100644 index 000000000..93ff3f89c --- /dev/null +++ b/src/Clipboard.cpp @@ -0,0 +1,56 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + Clipboard.cpp + +*//*******************************************************************/ + +#include "Clipboard.h" +#include "Track.h" + +wxDEFINE_EVENT( EVT_CLIPBOARD_CHANGE, wxCommandEvent); + +Clipboard::Clipboard() +: mTracks { TrackList::Create() } +{ +} + +Clipboard::~Clipboard() = default; + +Clipboard &Clipboard::Get() +{ + static Clipboard instance; + return instance; +} + +//static +const TrackList &Clipboard::GetTracks() const +{ + return *mTracks; +} + +void Clipboard::Clear() +{ + mT0 = 0.0; + mT1 = 0.0; + mProject = nullptr; + mTracks->Clear(); + + // Emit an event for listeners + AddPendingEvent( wxCommandEvent{ EVT_CLIPBOARD_CHANGE } ); +} + +void Clipboard::Assign( TrackList && newContents, + double t0, double t1, AudacityProject *pProject ) +{ + newContents.Swap( *mTracks ); + newContents.Clear(); + + mT0 = t0; + mT1 = t1; + mProject = pProject; + + // Emit an event for listeners + AddPendingEvent( wxCommandEvent{ EVT_CLIPBOARD_CHANGE } ); +} diff --git a/src/Clipboard.h b/src/Clipboard.h new file mode 100644 index 000000000..ead19df76 --- /dev/null +++ b/src/Clipboard.h @@ -0,0 +1,56 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + Clipboard.h + + Paul Licameli + +**********************************************************************/ + +#ifndef __AUDACITY_CLIPBOARD__ +#define __AUDACITY_CLIPBOARD__ + +#include "Audacity.h" + +#include +#include // to inherit wxEvtHandler + +class AudacityProject; +class TrackList; + +// An event emitted by the clipboard whenever its contents change. +wxDECLARE_EXPORTED_EVENT( AUDACITY_DLL_API, + EVT_CLIPBOARD_CHANGE, wxCommandEvent ); + +class Clipboard final + : public wxEvtHandler +{ +public: + static Clipboard &Get(); + + const TrackList &GetTracks() const; + + double T0() const { return mT0; } + double T1() const { return mT1; } + double Duration() const { return mT1 - mT0; } + + AudacityProject *Project() const { return mProject; } + + void Clear(); + + void Assign( + TrackList && newContents, double t0, double t1, + AudacityProject *pProject ); + +private: + Clipboard(); + ~Clipboard(); + + std::shared_ptr mTracks; + AudacityProject *mProject{}; + double mT0{ 0 }; + double mT1{ 0 }; +}; + +#endif diff --git a/src/DirManager.cpp b/src/DirManager.cpp index 3eef496a8..61b25f7aa 100644 --- a/src/DirManager.cpp +++ b/src/DirManager.cpp @@ -87,6 +87,7 @@ #endif #include "AudacityApp.h" +#include "Clipboard.h" #include "FileNames.h" #include "blockfile/LegacyBlockFile.h" #include "blockfile/LegacyAliasBlockFile.h" @@ -2124,13 +2125,11 @@ void DirManager::FindOrphanBlockFiles( ext.IsSameAs(wxT("auf"), false))) { if (!clipboardDM) { - TrackList *clipTracks = AudacityProject::GetClipboardTracks(); + auto &clipTracks = Clipboard::Get().GetTracks(); - if (clipTracks) { - auto track = *clipTracks->Any().first; - if (track) - clipboardDM = track->GetDirManager().get(); - } + auto track = *clipTracks.Any().first; + if (track) + clipboardDM = track->GetDirManager().get(); } // Ignore it if it exists in the clipboard (from a previously closed project) diff --git a/src/HistoryWindow.cpp b/src/HistoryWindow.cpp index d6c402d6c..34c9c3ddd 100644 --- a/src/HistoryWindow.cpp +++ b/src/HistoryWindow.cpp @@ -33,7 +33,7 @@ undo memory so as to free up space. #include #include "AudioIO.h" -#include "AudacityApp.h" +#include "Clipboard.h" #include "../images/Arrow.xpm" #include "../images/Empty9x16.xpm" #include "UndoManager.h" @@ -155,7 +155,8 @@ HistoryWindow::HistoryWindow(AudacityProject *parent, UndoManager *manager): &HistoryWindow::OnAudioIO, this); - wxTheApp->Bind(EVT_CLIPBOARD_CHANGE, &HistoryWindow::UpdateDisplay, this); + Clipboard::Get().Bind( + EVT_CLIPBOARD_CHANGE, &HistoryWindow::UpdateDisplay, this); manager->Bind(EVT_UNDO_PUSHED, &HistoryWindow::UpdateDisplay, this); manager->Bind(EVT_UNDO_MODIFIED, &HistoryWindow::UpdateDisplay, this); manager->Bind(EVT_UNDO_RESET, &HistoryWindow::UpdateDisplay, this); @@ -263,8 +264,7 @@ void HistoryWindow::OnDiscard(wxCommandEvent & WXUNUSED(event)) void HistoryWindow::OnDiscardClipboard(wxCommandEvent & WXUNUSED(event)) { - AudacityProject::ClearClipboard(); - DoUpdate(); + Clipboard::Get().Clear(); } void HistoryWindow::OnItemSelected(wxListEvent &event) diff --git a/src/Makefile.am b/src/Makefile.am index c2d1c7c35..8f4eb364d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -125,6 +125,8 @@ audacity_SOURCES = \ Benchmark.h \ CellularPanel.cpp \ CellularPanel.h \ + Clipboard.cpp \ + Clipboard.h \ Dependencies.cpp \ Dependencies.h \ DeviceChange.cpp \ diff --git a/src/Makefile.in b/src/Makefile.in index cb214204f..51714145c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -297,23 +297,23 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \ AutoRecovery.h BatchCommandDialog.cpp BatchCommandDialog.h \ BatchCommands.cpp BatchCommands.h BatchProcessDialog.cpp \ BatchProcessDialog.h Benchmark.cpp Benchmark.h \ - CellularPanel.cpp CellularPanel.h Dependencies.cpp \ - Dependencies.h DeviceChange.cpp DeviceChange.h \ - DeviceManager.cpp DeviceManager.h Diags.cpp Diags.h \ - Envelope.cpp Envelope.h Experimental.h FFmpeg.cpp FFmpeg.h \ - FFT.cpp FFT.h FileException.cpp FileException.h FileIO.cpp \ - FileIO.h FileNames.cpp FileNames.h float_cast.h FreqWindow.cpp \ - FreqWindow.h HelpText.cpp HelpText.h HistoryWindow.cpp \ - HistoryWindow.h HitTestResult.h ImageManipulation.cpp \ - ImageManipulation.h InconsistencyException.cpp \ - InconsistencyException.h InterpolateAudio.cpp \ - InterpolateAudio.h LabelDialog.cpp LabelDialog.h \ - LabelTrack.cpp LabelTrack.h LangChoice.cpp LangChoice.h \ - Languages.cpp Languages.h Legacy.cpp Legacy.h Lyrics.cpp \ - Lyrics.h LyricsWindow.cpp LyricsWindow.h MacroMagic.h \ - Matrix.cpp Matrix.h MemoryX.h Menus.cpp Menus.h Mix.cpp Mix.h \ - MixerBoard.cpp MixerBoard.h ModuleManager.cpp ModuleManager.h \ - NumberScale.h PitchName.cpp PitchName.h \ + CellularPanel.cpp CellularPanel.h Clipboard.cpp Clipboard.h \ + Dependencies.cpp Dependencies.h DeviceChange.cpp \ + DeviceChange.h DeviceManager.cpp DeviceManager.h Diags.cpp \ + Diags.h Envelope.cpp Envelope.h Experimental.h FFmpeg.cpp \ + FFmpeg.h FFT.cpp FFT.h FileException.cpp FileException.h \ + FileIO.cpp FileIO.h FileNames.cpp FileNames.h float_cast.h \ + FreqWindow.cpp FreqWindow.h HelpText.cpp HelpText.h \ + HistoryWindow.cpp HistoryWindow.h HitTestResult.h \ + ImageManipulation.cpp ImageManipulation.h \ + InconsistencyException.cpp InconsistencyException.h \ + InterpolateAudio.cpp InterpolateAudio.h LabelDialog.cpp \ + LabelDialog.h LabelTrack.cpp LabelTrack.h LangChoice.cpp \ + LangChoice.h Languages.cpp Languages.h Legacy.cpp Legacy.h \ + Lyrics.cpp Lyrics.h LyricsWindow.cpp LyricsWindow.h \ + MacroMagic.h Matrix.cpp Matrix.h MemoryX.h Menus.cpp Menus.h \ + Mix.cpp Mix.h MixerBoard.cpp MixerBoard.h ModuleManager.cpp \ + ModuleManager.h NumberScale.h PitchName.cpp PitchName.h \ PlatformCompatibility.cpp PlatformCompatibility.h \ PluginManager.cpp PluginManager.h Printing.cpp Printing.h \ Profiler.cpp Profiler.h Project.cpp Project.h RealFFTf.cpp \ @@ -633,7 +633,7 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \ audacity-BatchCommands.$(OBJEXT) \ audacity-BatchProcessDialog.$(OBJEXT) \ audacity-Benchmark.$(OBJEXT) audacity-CellularPanel.$(OBJEXT) \ - audacity-Dependencies.$(OBJEXT) \ + audacity-Clipboard.$(OBJEXT) audacity-Dependencies.$(OBJEXT) \ audacity-DeviceChange.$(OBJEXT) \ audacity-DeviceManager.$(OBJEXT) audacity-Diags.$(OBJEXT) \ audacity-Envelope.$(OBJEXT) audacity-FFmpeg.$(OBJEXT) \ @@ -1347,23 +1347,23 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \ AutoRecovery.h BatchCommandDialog.cpp BatchCommandDialog.h \ BatchCommands.cpp BatchCommands.h BatchProcessDialog.cpp \ BatchProcessDialog.h Benchmark.cpp Benchmark.h \ - CellularPanel.cpp CellularPanel.h Dependencies.cpp \ - Dependencies.h DeviceChange.cpp DeviceChange.h \ - DeviceManager.cpp DeviceManager.h Diags.cpp Diags.h \ - Envelope.cpp Envelope.h Experimental.h FFmpeg.cpp FFmpeg.h \ - FFT.cpp FFT.h FileException.cpp FileException.h FileIO.cpp \ - FileIO.h FileNames.cpp FileNames.h float_cast.h FreqWindow.cpp \ - FreqWindow.h HelpText.cpp HelpText.h HistoryWindow.cpp \ - HistoryWindow.h HitTestResult.h ImageManipulation.cpp \ - ImageManipulation.h InconsistencyException.cpp \ - InconsistencyException.h InterpolateAudio.cpp \ - InterpolateAudio.h LabelDialog.cpp LabelDialog.h \ - LabelTrack.cpp LabelTrack.h LangChoice.cpp LangChoice.h \ - Languages.cpp Languages.h Legacy.cpp Legacy.h Lyrics.cpp \ - Lyrics.h LyricsWindow.cpp LyricsWindow.h MacroMagic.h \ - Matrix.cpp Matrix.h MemoryX.h Menus.cpp Menus.h Mix.cpp Mix.h \ - MixerBoard.cpp MixerBoard.h ModuleManager.cpp ModuleManager.h \ - NumberScale.h PitchName.cpp PitchName.h \ + CellularPanel.cpp CellularPanel.h Clipboard.cpp Clipboard.h \ + Dependencies.cpp Dependencies.h DeviceChange.cpp \ + DeviceChange.h DeviceManager.cpp DeviceManager.h Diags.cpp \ + Diags.h Envelope.cpp Envelope.h Experimental.h FFmpeg.cpp \ + FFmpeg.h FFT.cpp FFT.h FileException.cpp FileException.h \ + FileIO.cpp FileIO.h FileNames.cpp FileNames.h float_cast.h \ + FreqWindow.cpp FreqWindow.h HelpText.cpp HelpText.h \ + HistoryWindow.cpp HistoryWindow.h HitTestResult.h \ + ImageManipulation.cpp ImageManipulation.h \ + InconsistencyException.cpp InconsistencyException.h \ + InterpolateAudio.cpp InterpolateAudio.h LabelDialog.cpp \ + LabelDialog.h LabelTrack.cpp LabelTrack.h LangChoice.cpp \ + LangChoice.h Languages.cpp Languages.h Legacy.cpp Legacy.h \ + Lyrics.cpp Lyrics.h LyricsWindow.cpp LyricsWindow.h \ + MacroMagic.h Matrix.cpp Matrix.h MemoryX.h Menus.cpp Menus.h \ + Mix.cpp Mix.h MixerBoard.cpp MixerBoard.h ModuleManager.cpp \ + ModuleManager.h NumberScale.h PitchName.cpp PitchName.h \ PlatformCompatibility.cpp PlatformCompatibility.h \ PluginManager.cpp PluginManager.h Printing.cpp Printing.h \ Profiler.cpp Profiler.h Project.cpp Project.h RealFFTf.cpp \ @@ -2492,6 +2492,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Benchmark.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-BlockFile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-CellularPanel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Clipboard.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Dependencies.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-DeviceChange.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-DeviceManager.Po@am__quote@ @@ -3399,6 +3400,20 @@ audacity-CellularPanel.obj: CellularPanel.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-CellularPanel.obj `if test -f 'CellularPanel.cpp'; then $(CYGPATH_W) 'CellularPanel.cpp'; else $(CYGPATH_W) '$(srcdir)/CellularPanel.cpp'; fi` +audacity-Clipboard.o: Clipboard.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-Clipboard.o -MD -MP -MF $(DEPDIR)/audacity-Clipboard.Tpo -c -o audacity-Clipboard.o `test -f 'Clipboard.cpp' || echo '$(srcdir)/'`Clipboard.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-Clipboard.Tpo $(DEPDIR)/audacity-Clipboard.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Clipboard.cpp' object='audacity-Clipboard.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-Clipboard.o `test -f 'Clipboard.cpp' || echo '$(srcdir)/'`Clipboard.cpp + +audacity-Clipboard.obj: Clipboard.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-Clipboard.obj -MD -MP -MF $(DEPDIR)/audacity-Clipboard.Tpo -c -o audacity-Clipboard.obj `if test -f 'Clipboard.cpp'; then $(CYGPATH_W) 'Clipboard.cpp'; else $(CYGPATH_W) '$(srcdir)/Clipboard.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-Clipboard.Tpo $(DEPDIR)/audacity-Clipboard.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Clipboard.cpp' object='audacity-Clipboard.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-Clipboard.obj `if test -f 'Clipboard.cpp'; then $(CYGPATH_W) 'Clipboard.cpp'; else $(CYGPATH_W) '$(srcdir)/Clipboard.cpp'; fi` + audacity-Dependencies.o: Dependencies.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-Dependencies.o -MD -MP -MF $(DEPDIR)/audacity-Dependencies.Tpo -c -o audacity-Dependencies.o `test -f 'Dependencies.cpp' || echo '$(srcdir)/'`Dependencies.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-Dependencies.Tpo $(DEPDIR)/audacity-Dependencies.Po diff --git a/src/Menus.cpp b/src/Menus.cpp index c8b648b31..e1345af23 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -33,6 +33,7 @@ #include "AdornedRulerPanel.h" #include "AudacityApp.h" #include "AudioIO.h" +#include "Clipboard.h" #include "LabelTrack.h" #include "ModuleManager.h" #ifdef USE_MIDI @@ -491,7 +492,7 @@ CommandFlag MenuManager::GetUpdateFlags #endif ); - if((AudacityProject::msClipT1 - AudacityProject::msClipT0) > 0.0) + if( Clipboard::Get().Duration() > 0 ) flags |= ClipboardFlag; auto &undoManager = *project.GetUndoManager(); diff --git a/src/Project.cpp b/src/Project.cpp index 7469ca484..d37cf6d1f 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -94,6 +94,7 @@ scroll information. It also has some status flags. #endif #include "AdornedRulerPanel.h" +#include "Clipboard.h" #include "FreqWindow.h" #include "effects/Contrast.h" #include "AutoRecovery.h" @@ -170,10 +171,6 @@ scroll information. It also has some status flags. #include "widgets/WindowAccessible.h" #endif -std::shared_ptr AudacityProject::msClipboard{ TrackList::Create() }; -double AudacityProject::msClipT0 = 0.0; -double AudacityProject::msClipT1 = 0.0; -AudacityProject *AudacityProject::msClipProject = NULL; ODLock &AudacityProject::AllProjectDeleteMutex() { static ODLock theMutex; @@ -2567,10 +2564,10 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event) quitOnClose = !mMenuClose; #endif - // DanH: If we're definitely about to quit, DELETE the clipboard. + // DanH: If we're definitely about to quit, clear the clipboard. // Doing this after Deref'ing the DirManager causes problems. if ((gAudacityProjects.size() == 1) && (quitOnClose || gIsQuitting)) - DeleteClipboard(); + Clipboard::Get().Clear(); // JKC: For Win98 and Linux do not detach the menu bar. // We want wxWidgets to clean it up for us. @@ -4694,32 +4691,6 @@ void AudacityProject::SetStateTo(unsigned int n) GetMenuManager(*this).ModifyUndoMenuItems(*this); } -// -// Clipboard methods -// - -//static -TrackList *AudacityProject::GetClipboardTracks() -{ - return msClipboard.get(); -} - -//static -void AudacityProject::DeleteClipboard() -{ - msClipboard.reset(); -} - -void AudacityProject::ClearClipboard() -{ - msClipT0 = 0.0; - msClipT1 = 0.0; - msClipProject = NULL; - if (msClipboard) { - msClipboard->Clear(); - } -} - // Utility function called by other zoom methods void AudacityProject::Zoom(double level) { diff --git a/src/Project.h b/src/Project.h index 5ed8eac77..a2bccba57 100644 --- a/src/Project.h +++ b/src/Project.h @@ -381,10 +381,7 @@ public: void ZoomOutByFactor( double ZoomFactor ); // Other commands - static TrackList *GetClipboardTracks(); - static void ClearClipboard(); - static void DeleteClipboard(); - + int GetProjectNumber(){ return mProjectNo;}; static int CountUnnamed(); static void RefreshAllTitles(bool bShowProjectNumbers ); @@ -583,13 +580,6 @@ public: std::shared_ptr mLastSavedTracks; public: - // Clipboard (static because it is shared by all projects) - static std::shared_ptr msClipboard; - static AudacityProject *msClipProject; - - static double msClipT0; - static double msClipT1; - ///Prevents DELETE from external thread - for e.g. use of GetActiveProject //shared by all projects static ODLock &AllProjectDeleteMutex(); diff --git a/src/UndoManager.cpp b/src/UndoManager.cpp index 91d9d39e1..d2397d558 100644 --- a/src/UndoManager.cpp +++ b/src/UndoManager.cpp @@ -26,6 +26,7 @@ UndoManager #include #include "BlockFile.h" +#include "Clipboard.h" #include "Diags.h" #include "Project.h" #include "Sequence.h" @@ -141,7 +142,7 @@ void UndoManager::CalculateSpaceUsage() } mClipboardSpaceUsage = CalculateUsage( - *AudacityProject::GetClipboardTracks(), nullptr); + Clipboard::Get().GetTracks(), nullptr); //TIMER_STOP( space_calc ); } diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index 9c2470c0b..1b415ec0b 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -1,6 +1,6 @@ #include "../Audacity.h" // for USE_* macros #include "../AdornedRulerPanel.h" -#include "../AudacityApp.h" // for EVT_CLIPBOARD_CHANGE +#include "../Clipboard.h" #include "../LabelTrack.h" #include "../Menus.h" #include "../NoteTrack.h" @@ -78,7 +78,8 @@ bool DoPasteNothingSelected(AudacityProject &project) return false; else { - auto clipTrackRange = AudacityProject::msClipboard->Any< const Track >(); + const auto &clipboard = Clipboard::Get(); + auto clipTrackRange = clipboard.GetTracks().Any< const Track >(); if (clipTrackRange.empty()) return true; // nothing to paste @@ -90,7 +91,7 @@ bool DoPasteNothingSelected(AudacityProject &project) Track *pNewTrack; pClip->TypeSwitch( [&](const WaveTrack *wc) { - if ((AudacityProject::msClipProject != &project)) + if ((clipboard.Project() != &project)) // Cause duplication of block files on disk, when copy is // between projects locker.create(wc); @@ -136,8 +137,8 @@ bool DoPasteNothingSelected(AudacityProject &project) // So do it at the sample rate of the project AudacityProject *p = GetActiveProject(); double projRate = p->GetRate(); - double quantT0 = QUANTIZED_TIME(AudacityProject::msClipT0, projRate); - double quantT1 = QUANTIZED_TIME(AudacityProject::msClipT1, projRate); + double quantT0 = QUANTIZED_TIME(clipboard.T0(), projRate); + double quantT1 = QUANTIZED_TIME(clipboard.T1(), projRate); selectedRegion.setTimes( 0.0, // anywhere else and this should be // half a sample earlier @@ -296,7 +297,8 @@ void OnCut(const CommandContext &context) } } - AudacityProject::ClearClipboard(); + auto &clipboard = Clipboard::Get(); + clipboard.Clear(); auto pNewClipboard = TrackList::Create(); auto &newClipboard = *pNewClipboard; @@ -318,8 +320,12 @@ void OnCut(const CommandContext &context) ); // Survived possibility of exceptions. Commit changes to the clipboard now. - newClipboard.Swap(*AudacityProject::msClipboard); - wxTheApp->AddPendingEvent( wxCommandEvent{ EVT_CLIPBOARD_CHANGE } ); + clipboard.Assign( + std::move( newClipboard ), + selectedRegion.t0(), + selectedRegion.t1(), + &project + ); // Proceed to change the project. If this throws, the project will be // rolled back by the top level handler. @@ -347,10 +353,6 @@ void OnCut(const CommandContext &context) } ); - AudacityProject::msClipT0 = selectedRegion.t0(); - AudacityProject::msClipT1 = selectedRegion.t1(); - AudacityProject::msClipProject = &project; - selectedRegion.collapseToT0(); project.PushState(_("Cut to the clipboard"), _("Cut")); @@ -401,7 +403,8 @@ void OnCopy(const CommandContext &context) } } - AudacityProject::ClearClipboard(); + auto &clipboard = Clipboard::Get(); + clipboard.Clear(); auto pNewClipboard = TrackList::Create(); auto &newClipboard = *pNewClipboard; @@ -413,12 +416,8 @@ void OnCopy(const CommandContext &context) } // Survived possibility of exceptions. Commit changes to the clipboard now. - newClipboard.Swap(*AudacityProject::msClipboard); - wxTheApp->AddPendingEvent( wxCommandEvent{ EVT_CLIPBOARD_CHANGE } ); - - AudacityProject::msClipT0 = selectedRegion.t0(); - AudacityProject::msClipT1 = selectedRegion.t1(); - AudacityProject::msClipProject = &project; + clipboard.Assign( std::move( newClipboard ), + selectedRegion.t0(), selectedRegion.t1(), &project ); //Make sure the menus/toolbar states get updated trackPanel->Refresh(false); @@ -441,7 +440,8 @@ void OnPaste(const CommandContext &context) if (DoPasteNothingSelected(project)) return; - auto clipTrackRange = AudacityProject::msClipboard->Any< const Track >(); + const auto &clipboard = Clipboard::Get(); + auto clipTrackRange = clipboard.GetTracks().Any< const Track >(); if (clipTrackRange.empty()) return; @@ -492,8 +492,7 @@ void OnPaste(const CommandContext &context) { // Must perform sync-lock adjustment before incrementing n if (n->IsSyncLockSelected()) { - auto newT1 = t0 + - (AudacityProject::msClipT1 - AudacityProject::msClipT0); + auto newT1 = t0 + clipboard.Duration(); if (t1 != newT1 && t1 <= n->GetEndTime()) { n->SyncLockAdjust(t1, newT1); bPastedSomething = true; @@ -554,7 +553,7 @@ void OnPaste(const CommandContext &context) n->TypeSwitch( [&](WaveTrack *wn){ const auto wc = static_cast(c); - if (AudacityProject::msClipProject != &project) + if (clipboard.Project() != &project) // Cause duplication of block files on disk, when copy is // between projects locker.create(wc); @@ -566,8 +565,7 @@ void OnPaste(const CommandContext &context) // a label track. ln->Clear(t0, t1); - ln->ShiftLabelsOnInsert( - AudacityProject::msClipT1 - AudacityProject::msClipT0, t0); + ln->ShiftLabelsOnInsert( clipboard.Duration(), t0 ); bPastedSomething |= ln->PasteOver(t0, c); }, @@ -611,8 +609,7 @@ void OnPaste(const CommandContext &context) } // if (n->GetSelected()) else if (n->IsSyncLockSelected()) { - auto newT1 = t0 + - (AudacityProject::msClipT1 - AudacityProject::msClipT0); + auto newT1 = t0 + clipboard.Duration(); if (t1 != newT1 && t1 <= n->GetEndTime()) { n->SyncLockAdjust(t1, newT1); bPastedSomething = true; @@ -628,9 +625,9 @@ void OnPaste(const CommandContext &context) if ( *pN && ! *pC ) { const auto wc = - *AudacityProject::msClipboard->Any< const WaveTrack >().rbegin(); + *clipboard.GetTracks().Any< const WaveTrack >().rbegin(); Maybe locker; - if (AudacityProject::msClipProject != &project && wc) + if (clipboard.Project() != &project && wc) // Cause duplication of block files on disk, when copy is // between projects locker.create(static_cast(wc)); @@ -647,9 +644,9 @@ void OnPaste(const CommandContext &context) else { auto tmp = trackFactory->NewWaveTrack( wt->GetSampleFormat(), wt->GetRate()); - tmp->InsertSilence(0.0, + tmp->InsertSilence( 0.0, // MJS: Is this correct? - AudacityProject::msClipT1 - AudacityProject::msClipT0); + clipboard.Duration() ); tmp->Flush(); bPastedSomething = true; @@ -665,12 +662,11 @@ void OnPaste(const CommandContext &context) // As above, only shift labels if sync-lock is on. if (isSyncLocked) lt->ShiftLabelsOnInsert( - AudacityProject::msClipT1 - AudacityProject::msClipT0, t0); + clipboard.Duration(), t0); }, [&](Track *n) { if (n->IsSyncLockSelected()) - n->SyncLockAdjust(t1, t0 + - AudacityProject::msClipT1 - AudacityProject::msClipT0); + n->SyncLockAdjust(t1, t0 + clipboard.Duration() ); } ); } @@ -679,8 +675,7 @@ void OnPaste(const CommandContext &context) if (bPastedSomething) { - selectedRegion.setT1( - t0 + AudacityProject::msClipT1 - AudacityProject::msClipT0); + selectedRegion.setT1( t0 + clipboard.Duration() ); project.PushState(_("Pasted from the clipboard"), _("Paste")); @@ -724,7 +719,8 @@ void OnSplitCut(const CommandContext &context) auto tracks = project.GetTracks(); auto &selectedRegion = project.GetViewInfo().selectedRegion; - AudacityProject::ClearClipboard(); + auto &clipboard = Clipboard::Get(); + clipboard.Clear(); auto pNewClipboard = TrackList::Create(); auto &newClipboard = *pNewClipboard; @@ -750,12 +746,8 @@ void OnSplitCut(const CommandContext &context) ); // Survived possibility of exceptions. Commit changes to the clipboard now. - newClipboard.Swap(*AudacityProject::msClipboard); - wxTheApp->AddPendingEvent( wxCommandEvent{ EVT_CLIPBOARD_CHANGE } ); - - AudacityProject::msClipT0 = selectedRegion.t0(); - AudacityProject::msClipT1 = selectedRegion.t1(); - AudacityProject::msClipProject = &project; + clipboard.Assign( std::move( newClipboard ), + selectedRegion.t0(), selectedRegion.t1(), &project ); project.PushState(_("Split-cut to the clipboard"), _("Split Cut")); diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index 05d9416bc..5cf0b04a8 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -1,5 +1,5 @@ -#include "../AudacityApp.h" // for EVT_CLIPBOARD_CHANGE #include "../AudioIO.h" +#include "../Clipboard.h" #include "../LabelTrack.h" #include "../Menus.h" #include "../Prefs.h" @@ -164,7 +164,7 @@ using EditDestFunction = std::shared_ptr (WaveTrack::*)(double, double); //Functions copy the edited regions to clipboard, possibly in multiple tracks //This probably should not be called if *action() changes the timeline, because // the copy needs to happen by track, and the timeline change by group. -void EditClipboardByLabel( +void EditClipboardByLabel( AudacityProject &project, TrackList &tracks, const SelectedRegion &selectedRegion, EditDestFunction action ) { @@ -178,7 +178,8 @@ void EditClipboardByLabel( // apply only on the selected track const bool allTracks = (tracks.Selected< WaveTrack >()).empty(); - AudacityProject::ClearClipboard(); + auto &clipboard = Clipboard::Get(); + clipboard.Clear(); auto pNewClipboard = TrackList::Create(); auto &newClipboard = *pNewClipboard; @@ -231,11 +232,8 @@ void EditClipboardByLabel( } // Survived possibility of exceptions. Commit changes to the clipboard now. - newClipboard.Swap(*AudacityProject::msClipboard); - wxTheApp->AddPendingEvent( wxCommandEvent{ EVT_CLIPBOARD_CHANGE } ); - - AudacityProject::msClipT0 = regions.front().start; - AudacityProject::msClipT1 = regions.back().end; + clipboard.Assign( std::move( newClipboard ), + regions.front().start, regions.back().end, &project ); } } @@ -363,7 +361,8 @@ void OnCutLabels(const CommandContext &context) // Because of grouping the copy may need to operate on different tracks than // the clear, so we do these actions separately. - EditClipboardByLabel( tracks, selectedRegion, &WaveTrack::CopyNonconst ); + EditClipboardByLabel( project, + tracks, selectedRegion, &WaveTrack::CopyNonconst ); if( gPrefs->Read( wxT( "/GUI/EnableCutLines" ), ( long )0 ) ) EditByLabel( @@ -371,8 +370,6 @@ void OnCutLabels(const CommandContext &context) else EditByLabel( tracks, selectedRegion, &WaveTrack::Clear, true ); - AudacityProject::msClipProject = &project; - selectedRegion.collapseToT0(); project.PushState( @@ -416,9 +413,8 @@ void OnSplitCutLabels(const CommandContext &context) if( selectedRegion.isPoint() ) return; - EditClipboardByLabel( tracks, selectedRegion, &WaveTrack::SplitCut ); - - AudacityProject::msClipProject = &project; + EditClipboardByLabel( project, + tracks, selectedRegion, &WaveTrack::SplitCut ); project.PushState( /* i18n-hint: (verb) Audacity has just split cut the labeled audio @@ -483,9 +479,8 @@ void OnCopyLabels(const CommandContext &context) if( selectedRegion.isPoint() ) return; - EditClipboardByLabel( tracks, selectedRegion, &WaveTrack::CopyNonconst ); - - AudacityProject::msClipProject = &project; + EditClipboardByLabel( project, + tracks, selectedRegion, &WaveTrack::CopyNonconst ); project.PushState( _( "Copied labeled audio regions to clipboard" ), /* i18n-hint: (verb)*/ diff --git a/win/Projects/Audacity/Audacity.vcxproj b/win/Projects/Audacity/Audacity.vcxproj index 9e57c4e69..68be730b7 100755 --- a/win/Projects/Audacity/Audacity.vcxproj +++ b/win/Projects/Audacity/Audacity.vcxproj @@ -137,6 +137,7 @@ + @@ -496,6 +497,7 @@ + @@ -1271,4 +1273,4 @@ - \ No newline at end of file + diff --git a/win/Projects/Audacity/Audacity.vcxproj.filters b/win/Projects/Audacity/Audacity.vcxproj.filters index 677663e4a..081b0a921 100755 --- a/win/Projects/Audacity/Audacity.vcxproj.filters +++ b/win/Projects/Audacity/Audacity.vcxproj.filters @@ -1088,6 +1088,9 @@ src + + src + src\menus @@ -2209,6 +2212,9 @@ src + + src + src @@ -2452,4 +2458,4 @@ Resources - \ No newline at end of file +