mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-04 22:49:07 +02:00
Preliminaries before further cycle-breaking
This commit is contained in:
commit
caec2064e5
@ -156,6 +156,8 @@ src/Profiler.cpp
|
||||
src/Profiler.h
|
||||
src/Project.cpp
|
||||
src/Project.h
|
||||
src/ProjectFileIORegistry.cpp
|
||||
src/ProjectFileIORegistry.h
|
||||
src/ProjectFSCK.cpp
|
||||
src/ProjectFSCK.h
|
||||
src/RealFFTf.cpp
|
||||
|
@ -1224,6 +1224,7 @@
|
||||
5E1512701DB0010C00702E29 /* TrackVRulerControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E15126B1DB0010C00702E29 /* TrackVRulerControls.cpp */; };
|
||||
5E16FF4D1FF9CE0B0085E1B8 /* LanguageNames.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5E16FF4C1FF9CE0B0085E1B8 /* LanguageNames.txt */; };
|
||||
5E18CFF322931D3D00E75250 /* AudacityMessageBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E18CFF222931D3D00E75250 /* AudacityMessageBox.cpp */; };
|
||||
5E18CFF02291C31000E75250 /* ProjectFileIORegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E18CFEE2291C31000E75250 /* ProjectFileIORegistry.cpp */; };
|
||||
5E19D655217D51190024D0B1 /* PluginMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E19D64C217D51190024D0B1 /* PluginMenus.cpp */; };
|
||||
5E2A19941EED688500217B58 /* SelectionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E2A19921EED688500217B58 /* SelectionState.cpp */; };
|
||||
5E36A0A8217FA2430068E082 /* EditMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E36A09F217FA2430068E082 /* EditMenus.cpp */; };
|
||||
@ -3198,6 +3199,8 @@
|
||||
5E16FF4C1FF9CE0B0085E1B8 /* LanguageNames.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LanguageNames.txt; path = ../locale/LanguageNames.txt; sourceTree = "<group>"; };
|
||||
5E18CFF122931CA900E75250 /* AudacityMessageBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudacityMessageBox.h; sourceTree = "<group>"; };
|
||||
5E18CFF222931D3D00E75250 /* AudacityMessageBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudacityMessageBox.cpp; sourceTree = "<group>"; };
|
||||
5E18CFEE2291C31000E75250 /* ProjectFileIORegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProjectFileIORegistry.cpp; sourceTree = "<group>"; };
|
||||
5E18CFEF2291C31000E75250 /* ProjectFileIORegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectFileIORegistry.h; sourceTree = "<group>"; };
|
||||
5E19D64C217D51190024D0B1 /* PluginMenus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PluginMenus.cpp; path = menus/PluginMenus.cpp; sourceTree = "<group>"; };
|
||||
5E2A19921EED688500217B58 /* SelectionState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionState.cpp; sourceTree = "<group>"; };
|
||||
5E2A19931EED688500217B58 /* SelectionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionState.h; sourceTree = "<group>"; };
|
||||
@ -4353,6 +4356,7 @@
|
||||
1790B0CE09883BFD008A330A /* Printing.cpp */,
|
||||
186CCEA30E523C8E00659159 /* Profiler.cpp */,
|
||||
1790B0D009883BFD008A330A /* Project.cpp */,
|
||||
5E18CFEE2291C31000E75250 /* ProjectFileIORegistry.cpp */,
|
||||
5ECF728C228B307E007F2A35 /* ProjectFSCK.cpp */,
|
||||
28DABFBC0FF19DB100AC7848 /* RealFFTf.cpp */,
|
||||
EDFCEBA218894B2A00C98E51 /* RealFFTf48x.cpp */,
|
||||
@ -4465,6 +4469,7 @@
|
||||
1790B0CF09883BFD008A330A /* Printing.h */,
|
||||
186CCEA20E523C8D00659159 /* Profiler.h */,
|
||||
1790B0D109883BFD008A330A /* Project.h */,
|
||||
5E18CFEF2291C31000E75250 /* ProjectFileIORegistry.h */,
|
||||
5ECF728B228B307E007F2A35 /* ProjectFSCK.h */,
|
||||
28DABFBD0FF19DB100AC7848 /* RealFFTf.h */,
|
||||
EDFCEBA318894B2A00C98E51 /* RealFFTf48x.h */,
|
||||
@ -8422,6 +8427,7 @@
|
||||
2897F6F00AB3DB5A003C20C5 /* ControlToolBar.cpp in Sources */,
|
||||
2897F6F10AB3DB5A003C20C5 /* EditToolBar.cpp in Sources */,
|
||||
2897F6F20AB3DB5A003C20C5 /* MeterToolBar.cpp in Sources */,
|
||||
5E18CFF02291C31000E75250 /* ProjectFileIORegistry.cpp in Sources */,
|
||||
2897F6F30AB3DB5A003C20C5 /* MixerToolBar.cpp in Sources */,
|
||||
2897F6F40AB3DB5A003C20C5 /* SelectionBar.cpp in Sources */,
|
||||
2897F6F50AB3DB5A003C20C5 /* ToolBar.cpp in Sources */,
|
||||
|
@ -130,6 +130,8 @@ public:
|
||||
private:
|
||||
AdornedRulerPanel *GetRuler() const;
|
||||
|
||||
unsigned SequenceNumber() const override;
|
||||
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw(OverlayPanel &panel, wxDC &dc) override;
|
||||
|
||||
@ -159,6 +161,7 @@ public:
|
||||
QuickPlayIndicatorOverlay(AudacityProject *project);
|
||||
|
||||
private:
|
||||
unsigned SequenceNumber() const override;
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw(OverlayPanel &panel, wxDC &dc) override;
|
||||
|
||||
@ -229,6 +232,12 @@ void AdornedRulerPanel::QuickPlayRulerOverlay::Update()
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
AdornedRulerPanel::QuickPlayRulerOverlay::SequenceNumber() const
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool>
|
||||
AdornedRulerPanel::QuickPlayRulerOverlay::DoGetRectangle(wxSize /*size*/)
|
||||
{
|
||||
@ -284,6 +293,12 @@ AdornedRulerPanel::QuickPlayIndicatorOverlay::QuickPlayIndicatorOverlay(
|
||||
{
|
||||
}
|
||||
|
||||
unsigned
|
||||
AdornedRulerPanel::QuickPlayIndicatorOverlay::SequenceNumber() const
|
||||
{
|
||||
return 30;
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool>
|
||||
AdornedRulerPanel::QuickPlayIndicatorOverlay::DoGetRectangle(wxSize size)
|
||||
{
|
||||
@ -878,6 +893,9 @@ AdornedRulerPanel::AdornedRulerPanel(AudacityProject* project,
|
||||
wxTheApp->Bind(EVT_AUDIOIO_CAPTURE,
|
||||
&AdornedRulerPanel::OnRecordStartStop,
|
||||
this);
|
||||
|
||||
// Delay until after CommandManager has been populated:
|
||||
this->CallAfter( &AdornedRulerPanel::UpdatePrefs );
|
||||
}
|
||||
|
||||
AdornedRulerPanel::~AdornedRulerPanel()
|
||||
@ -905,6 +923,14 @@ namespace {
|
||||
|
||||
void AdornedRulerPanel::UpdatePrefs()
|
||||
{
|
||||
if (mNeedButtonUpdate) {
|
||||
// Visit this block once only in the lifetime of this panel
|
||||
mNeedButtonUpdate = false;
|
||||
// Do this first time setting of button status texts
|
||||
// when we are sure the CommandManager is initialized.
|
||||
ReCreateButtons();
|
||||
}
|
||||
|
||||
// Update button texts for language change
|
||||
UpdateButtonStates();
|
||||
|
||||
@ -1087,16 +1113,6 @@ void AdornedRulerPanel::OnRecordStartStop(wxCommandEvent & evt)
|
||||
|
||||
void AdornedRulerPanel::OnPaint(wxPaintEvent & WXUNUSED(evt))
|
||||
{
|
||||
if (mNeedButtonUpdate) {
|
||||
// Visit this block once only in the lifetime of this panel
|
||||
mNeedButtonUpdate = false;
|
||||
// Do this first time setting of button status texts
|
||||
// when we are sure the CommandManager is initialized.
|
||||
ReCreateButtons();
|
||||
// Sends a resize event, which will cause a second paint.
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
wxPaintDC dc(this);
|
||||
|
||||
auto &backDC = GetBackingDCForRepaint();
|
||||
@ -1574,18 +1590,17 @@ void AdornedRulerPanel::StartQPPlay(bool looped, bool cutPreview)
|
||||
else
|
||||
options.timeTrack = NULL;
|
||||
|
||||
ControlToolBar::PlayAppearance appearance =
|
||||
cutPreview ? ControlToolBar::PlayAppearance::CutPreview
|
||||
: options.playLooped ? ControlToolBar::PlayAppearance::Looped
|
||||
: ControlToolBar::PlayAppearance::Straight;
|
||||
auto mode =
|
||||
cutPreview ? PlayMode::cutPreviewPlay
|
||||
: options.playLooped ? PlayMode::loopedPlay
|
||||
: PlayMode::normalPlay;
|
||||
|
||||
mPlayRegionStart = start;
|
||||
mPlayRegionEnd = end;
|
||||
Refresh();
|
||||
|
||||
ctb->PlayPlayRegion((SelectedRegion(start, end)),
|
||||
options, PlayMode::normalPlay,
|
||||
appearance,
|
||||
options, mode,
|
||||
false,
|
||||
true);
|
||||
|
||||
@ -1785,8 +1800,11 @@ void AdornedRulerPanel::OnAutoScroll(wxCommandEvent&)
|
||||
gPrefs->Write(wxT("/GUI/AutoScroll"), false);
|
||||
else
|
||||
gPrefs->Write(wxT("/GUI/AutoScroll"), true);
|
||||
mProject->UpdatePrefs();
|
||||
|
||||
gPrefs->Flush();
|
||||
|
||||
wxTheApp->AddPendingEvent(wxCommandEvent{
|
||||
EVT_PREFS_UPDATE, ViewInfo::UpdateScrollPrefsID() });
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "CellularPanel.h"
|
||||
#include "widgets/Ruler.h" // member variable
|
||||
#include "Prefs.h"
|
||||
|
||||
class ViewInfo;
|
||||
class AudacityProject;
|
||||
@ -20,7 +21,9 @@ class SnapManager;
|
||||
class TrackList;
|
||||
|
||||
// This is an Audacity Specific ruler panel.
|
||||
class AUDACITY_DLL_API AdornedRulerPanel final : public CellularPanel
|
||||
class AUDACITY_DLL_API AdornedRulerPanel final
|
||||
: public CellularPanel
|
||||
, private PrefsListener
|
||||
{
|
||||
public:
|
||||
AdornedRulerPanel(AudacityProject *project,
|
||||
@ -53,7 +56,7 @@ public:
|
||||
|
||||
void InvalidateRuler();
|
||||
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
void ReCreateButtons();
|
||||
|
||||
void RegenerateTooltips();
|
||||
|
@ -1005,9 +1005,9 @@ Choose Help > Diagnostics > Check Dependencies to view a list of \
|
||||
locations of the missing files."), missingFileName);
|
||||
|
||||
// if an old dialog exists, raise it if it is
|
||||
if (offendingProject->GetMissingAliasFileDialog()) {
|
||||
offendingProject->GetMissingAliasFileDialog()->Raise();
|
||||
} else {
|
||||
if ( auto dialog = MissingAliasFilesDialog::Find( *offendingProject ) )
|
||||
dialog->Raise();
|
||||
else {
|
||||
MissingAliasFilesDialog::Show(offendingProject.get(), _("Files Missing"),
|
||||
errorMessage, wxT(""), true);
|
||||
}
|
||||
|
@ -5371,7 +5371,7 @@ void AudioIoCallback::SendVuOutputMeterData(
|
||||
//MixerBoard* pMixerBoard = mOwningProject->GetMixerBoard();
|
||||
//if (pMixerBoard)
|
||||
// pMixerBoard->UpdateMeters(GetStreamTime(),
|
||||
// (pProj->mLastPlayMode == loopedPlay));
|
||||
// (pProj->GetControlToolBar()->GetLastPlayMode() == loopedPlay));
|
||||
}
|
||||
mUpdatingMeters = false;
|
||||
}
|
||||
|
@ -729,7 +729,7 @@ bool MacroCommands::ApplyEffectCommand(
|
||||
// IF nothing selected, THEN select everything
|
||||
// (most effects require that you have something selected).
|
||||
if( plug->GetPluginType() != PluginTypeAudacityCommand )
|
||||
project->SelectAllIfNone();
|
||||
SelectActions::SelectAllIfNone( *project );
|
||||
|
||||
bool res = false;
|
||||
|
||||
|
@ -63,6 +63,7 @@ for drawing different aspects of the label and its text box.
|
||||
#include "AllThemeResources.h"
|
||||
#include "AColor.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectFileIORegistry.h"
|
||||
#include "TrackArtist.h"
|
||||
#include "TrackPanel.h"
|
||||
#include "UndoManager.h"
|
||||
@ -98,6 +99,15 @@ int LabelTrack::mTextHeight;
|
||||
|
||||
int LabelTrack::mFontHeight=-1;
|
||||
|
||||
static ProjectFileIORegistry::Entry registerFactory{
|
||||
wxT( "labeltrack" ),
|
||||
[]( AudacityProject &project ){
|
||||
auto &trackFactory = *project.GetTrackFactory();
|
||||
auto &tracks = *project.GetTracks();
|
||||
return tracks.Add(trackFactory.NewLabelTrack());
|
||||
}
|
||||
};
|
||||
|
||||
LabelTrack::Holder TrackFactory::NewLabelTrack()
|
||||
{
|
||||
return std::make_shared<LabelTrack>(mDirManager);
|
||||
|
@ -207,6 +207,8 @@ audacity_SOURCES = \
|
||||
Profiler.h \
|
||||
Project.cpp \
|
||||
Project.h \
|
||||
ProjectFileIORegistry.cpp \
|
||||
ProjectFileIORegistry.h \
|
||||
ProjectFSCK.cpp \
|
||||
ProjectFSCK.h \
|
||||
RealFFTf.cpp \
|
||||
|
@ -319,10 +319,11 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \
|
||||
PitchName.cpp PitchName.h PlatformCompatibility.cpp \
|
||||
PlatformCompatibility.h PluginManager.cpp PluginManager.h \
|
||||
Printing.cpp Printing.h Profiler.cpp Profiler.h Project.cpp \
|
||||
Project.h ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp \
|
||||
RealFFTf.h RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h \
|
||||
Resample.cpp Resample.h RevisionIdent.h RingBuffer.cpp \
|
||||
RingBuffer.h Screenshot.cpp Screenshot.h SelectedRegion.cpp \
|
||||
Project.h ProjectFileIORegistry.cpp ProjectFileIORegistry.h \
|
||||
ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp RealFFTf.h \
|
||||
RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h Resample.cpp \
|
||||
Resample.h RevisionIdent.h RingBuffer.cpp RingBuffer.h \
|
||||
Screenshot.cpp Screenshot.h SelectedRegion.cpp \
|
||||
SelectedRegion.h SelectionState.cpp SelectionState.h \
|
||||
Shuttle.cpp Shuttle.h ShuttleGetDefinition.cpp \
|
||||
ShuttleGetDefinition.h ShuttleGui.cpp ShuttleGui.h \
|
||||
@ -662,6 +663,7 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \
|
||||
audacity-PlatformCompatibility.$(OBJEXT) \
|
||||
audacity-PluginManager.$(OBJEXT) audacity-Printing.$(OBJEXT) \
|
||||
audacity-Profiler.$(OBJEXT) audacity-Project.$(OBJEXT) \
|
||||
audacity-ProjectFileIORegistry.$(OBJEXT) \
|
||||
audacity-ProjectFSCK.$(OBJEXT) audacity-RealFFTf.$(OBJEXT) \
|
||||
audacity-RealFFTf48x.$(OBJEXT) audacity-Resample.$(OBJEXT) \
|
||||
audacity-RingBuffer.$(OBJEXT) audacity-Screenshot.$(OBJEXT) \
|
||||
@ -1378,10 +1380,11 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \
|
||||
PitchName.cpp PitchName.h PlatformCompatibility.cpp \
|
||||
PlatformCompatibility.h PluginManager.cpp PluginManager.h \
|
||||
Printing.cpp Printing.h Profiler.cpp Profiler.h Project.cpp \
|
||||
Project.h ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp \
|
||||
RealFFTf.h RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h \
|
||||
Resample.cpp Resample.h RevisionIdent.h RingBuffer.cpp \
|
||||
RingBuffer.h Screenshot.cpp Screenshot.h SelectedRegion.cpp \
|
||||
Project.h ProjectFileIORegistry.cpp ProjectFileIORegistry.h \
|
||||
ProjectFSCK.cpp ProjectFSCK.h RealFFTf.cpp RealFFTf.h \
|
||||
RealFFTf48x.cpp RealFFTf48x.h RefreshCode.h Resample.cpp \
|
||||
Resample.h RevisionIdent.h RingBuffer.cpp RingBuffer.h \
|
||||
Screenshot.cpp Screenshot.h SelectedRegion.cpp \
|
||||
SelectedRegion.h SelectionState.cpp SelectionState.h \
|
||||
Shuttle.cpp Shuttle.h ShuttleGetDefinition.cpp \
|
||||
ShuttleGetDefinition.h ShuttleGui.cpp ShuttleGui.h \
|
||||
@ -2553,6 +2556,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Profiler.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Project.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-ProjectFSCK.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-ProjectFileIORegistry.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-RealFFTf.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-RealFFTf48x.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Resample.Po@am__quote@
|
||||
@ -3954,6 +3958,20 @@ audacity-Project.obj: Project.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-Project.obj `if test -f 'Project.cpp'; then $(CYGPATH_W) 'Project.cpp'; else $(CYGPATH_W) '$(srcdir)/Project.cpp'; fi`
|
||||
|
||||
audacity-ProjectFileIORegistry.o: ProjectFileIORegistry.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ProjectFileIORegistry.o -MD -MP -MF $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo -c -o audacity-ProjectFileIORegistry.o `test -f 'ProjectFileIORegistry.cpp' || echo '$(srcdir)/'`ProjectFileIORegistry.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo $(DEPDIR)/audacity-ProjectFileIORegistry.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ProjectFileIORegistry.cpp' object='audacity-ProjectFileIORegistry.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-ProjectFileIORegistry.o `test -f 'ProjectFileIORegistry.cpp' || echo '$(srcdir)/'`ProjectFileIORegistry.cpp
|
||||
|
||||
audacity-ProjectFileIORegistry.obj: ProjectFileIORegistry.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ProjectFileIORegistry.obj -MD -MP -MF $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo -c -o audacity-ProjectFileIORegistry.obj `if test -f 'ProjectFileIORegistry.cpp'; then $(CYGPATH_W) 'ProjectFileIORegistry.cpp'; else $(CYGPATH_W) '$(srcdir)/ProjectFileIORegistry.cpp'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ProjectFileIORegistry.Tpo $(DEPDIR)/audacity-ProjectFileIORegistry.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ProjectFileIORegistry.cpp' object='audacity-ProjectFileIORegistry.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-ProjectFileIORegistry.obj `if test -f 'ProjectFileIORegistry.cpp'; then $(CYGPATH_W) 'ProjectFileIORegistry.cpp'; else $(CYGPATH_W) '$(srcdir)/ProjectFileIORegistry.cpp'; fi`
|
||||
|
||||
audacity-ProjectFSCK.o: ProjectFSCK.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ProjectFSCK.o -MD -MP -MF $(DEPDIR)/audacity-ProjectFSCK.Tpo -c -o audacity-ProjectFSCK.o `test -f 'ProjectFSCK.cpp' || echo '$(srcdir)/'`ProjectFSCK.cpp
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ProjectFSCK.Tpo $(DEPDIR)/audacity-ProjectFSCK.Po
|
||||
|
@ -51,14 +51,6 @@
|
||||
|
||||
#include <wx/menu.h>
|
||||
|
||||
PrefsListener::~PrefsListener()
|
||||
{
|
||||
}
|
||||
|
||||
void PrefsListener::UpdatePrefs()
|
||||
{
|
||||
}
|
||||
|
||||
MenuManager &GetMenuManager(AudacityProject &project)
|
||||
{ return *project.mMenuManager; }
|
||||
|
||||
@ -70,6 +62,11 @@ MenuCreator::~MenuCreator()
|
||||
{
|
||||
}
|
||||
|
||||
MenuManager::MenuManager()
|
||||
{
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
void MenuManager::UpdatePrefs()
|
||||
{
|
||||
bool bSelectAllIfNone;
|
||||
@ -388,6 +385,7 @@ CommandFlag MenuManager::GetFocusedFrame(AudacityProject &project)
|
||||
return AlwaysEnabledFlag;
|
||||
}
|
||||
|
||||
|
||||
CommandFlag MenuManager::GetUpdateFlags
|
||||
(AudacityProject &project, bool checkActive)
|
||||
{
|
||||
@ -548,7 +546,7 @@ CommandFlag MenuManager::GetUpdateFlags
|
||||
if (!EffectManager::Get().RealtimeIsActive())
|
||||
flags |= IsRealtimeNotActiveFlag;
|
||||
|
||||
if (!project.IsCapturing())
|
||||
if ( !( gAudioIO->IsBusy() && gAudioIO->GetNumCaptureChannels() > 0 ) )
|
||||
flags |= CaptureNotBusyFlag;
|
||||
|
||||
ControlToolBar *bar = project.GetControlToolBar();
|
||||
@ -781,7 +779,7 @@ bool MenuManager::TryToMakeActionAllowed
|
||||
auto MissingFlags = (~flags & flagsRqd) & mask;
|
||||
|
||||
if( mStopIfWasPaused && (MissingFlags & AudioIONotBusyFlag ) ){
|
||||
project.StopIfPaused();
|
||||
TransportActions::StopIfPaused( project );
|
||||
// Hope this will now reflect stopped audio.
|
||||
flags = GetMenuManager(project).GetUpdateFlags(project);
|
||||
bAllowed = ((flags & mask) == (flagsRqd & mask));
|
||||
|
17
src/Menus.h
17
src/Menus.h
@ -13,6 +13,7 @@
|
||||
#include "audacity/Types.h"
|
||||
|
||||
#include <wx/string.h> // member variable
|
||||
#include "Prefs.h"
|
||||
|
||||
class wxArrayString;
|
||||
class AudacityProject;
|
||||
@ -32,13 +33,6 @@ enum EffectType : int;
|
||||
typedef wxString PluginID;
|
||||
typedef wxArrayString PluginIDs;
|
||||
|
||||
class PrefsListener
|
||||
{
|
||||
public:
|
||||
virtual ~PrefsListener();
|
||||
virtual void UpdatePrefs(); // default is no-op
|
||||
};
|
||||
|
||||
class MenuCreator
|
||||
{
|
||||
public:
|
||||
@ -56,9 +50,11 @@ public:
|
||||
PluginID mLastEffect{};
|
||||
};
|
||||
|
||||
class MenuManager : public MenuCreator
|
||||
class MenuManager final : public MenuCreator, private PrefsListener
|
||||
{
|
||||
public:
|
||||
MenuManager();
|
||||
|
||||
static void ModifyUndoMenuItems(AudacityProject &project);
|
||||
static void ModifyToolbarMenus(AudacityProject &project);
|
||||
// Calls ModifyToolbarMenus() on all projects
|
||||
@ -72,7 +68,7 @@ public:
|
||||
// inactive project as it is needlessly expensive.
|
||||
CommandFlag GetUpdateFlags(
|
||||
AudacityProject &project, bool checkActive = false);
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
|
||||
// Command Handling
|
||||
bool ReportIfActionNotAllowed(
|
||||
@ -115,6 +111,8 @@ void DoUndo( AudacityProject &project );
|
||||
|
||||
/// Namespace for functions for Select menu
|
||||
namespace SelectActions {
|
||||
void SelectAllIfNone( AudacityProject &project );
|
||||
void SelectNone( AudacityProject &project );
|
||||
void DoListSelection(
|
||||
AudacityProject &project, Track *t,
|
||||
bool shift, bool ctrl, bool modifyState );
|
||||
@ -132,6 +130,7 @@ void DoZoomFitV( AudacityProject &project );
|
||||
|
||||
/// Namespace for functions for Transport menu
|
||||
namespace TransportActions {
|
||||
void StopIfPaused( AudacityProject &project );
|
||||
bool DoPlayStopSelect( AudacityProject &project, bool click, bool shift );
|
||||
void DoPlayStopSelect( AudacityProject &project );
|
||||
void DoStop( AudacityProject & );
|
||||
|
@ -14,11 +14,16 @@
|
||||
#include "Project.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
|
||||
namespace {
|
||||
using wxDialogRef = wxWeakRef< wxDialog >;
|
||||
std::vector< wxDialogRef > sDialogs;
|
||||
}
|
||||
|
||||
// special case for alias missing dialog because we keep track of if it exists.
|
||||
class MissingAliasFileDialog final : public ErrorDialog
|
||||
{
|
||||
public:
|
||||
MissingAliasFileDialog(AudacityProject *parent,
|
||||
MissingAliasFileDialog(wxWindow *parent,
|
||||
const wxString & dlogTitle,
|
||||
const wxString & message,
|
||||
const wxString & helpURL,
|
||||
@ -27,20 +32,23 @@ class MissingAliasFileDialog final : public ErrorDialog
|
||||
};
|
||||
|
||||
|
||||
MissingAliasFileDialog::MissingAliasFileDialog(AudacityProject *parent,
|
||||
MissingAliasFileDialog::MissingAliasFileDialog(wxWindow *parent,
|
||||
const wxString & dlogTitle,
|
||||
const wxString & message,
|
||||
const wxString & helpURL,
|
||||
const bool Close, const bool modal):
|
||||
ErrorDialog(parent, dlogTitle, message, helpURL, Close, modal)
|
||||
{
|
||||
parent->SetMissingAliasFileDialog(this);
|
||||
sDialogs.push_back( this );
|
||||
}
|
||||
|
||||
MissingAliasFileDialog::~MissingAliasFileDialog()
|
||||
{
|
||||
static_cast<AudacityProject *>(GetParent())
|
||||
->SetMissingAliasFileDialog( nullptr );
|
||||
auto begin = sDialogs.begin(), end = sDialogs.end(),
|
||||
newEnd = std::remove_if( begin, end,
|
||||
[&]( const wxDialogRef &ref ){
|
||||
return ref == this; } );
|
||||
sDialogs.erase( newEnd, end );
|
||||
}
|
||||
|
||||
namespace MissingAliasFilesDialog {
|
||||
@ -82,6 +90,17 @@ namespace MissingAliasFilesDialog {
|
||||
// but in practice Destroy() in OnOK does that
|
||||
}
|
||||
|
||||
wxDialog *Find( const AudacityProject &project )
|
||||
{
|
||||
auto begin = sDialogs.begin(), end = sDialogs.end(),
|
||||
iter = std::find_if( begin, end,
|
||||
[&]( const wxDialogRef &ref ){
|
||||
return ref && ref->GetParent() == &project; } );
|
||||
if (iter != end)
|
||||
return *iter;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Mark(const AliasBlockFile *b)
|
||||
{
|
||||
Lock lock{ m_LastMissingBlockFileLock };
|
||||
|
@ -37,6 +37,8 @@ void Show(AudacityProject *parent,
|
||||
const wxString &helpPage,
|
||||
const bool Close = true);
|
||||
|
||||
wxDialog *Find( const AudacityProject &project );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -54,6 +54,7 @@
|
||||
#endif
|
||||
|
||||
#include "commands/CommandManager.h"
|
||||
#include "toolbars/ControlToolBar.h"
|
||||
|
||||
// class MixerTrackSlider
|
||||
|
||||
@ -355,8 +356,6 @@ void MixerTrackCluster::UpdatePrefs()
|
||||
{
|
||||
this->SetBackgroundColour( theTheme.Colour( clrMedium ) );
|
||||
mStaticText_TrackName->SetForegroundColour(theTheme.Colour(clrTrackPanelText));
|
||||
if (mMeter)
|
||||
mMeter->UpdatePrefs(); // in case meter range has changed
|
||||
HandleResize(); // in case prefs "/GUI/Solo" changed
|
||||
}
|
||||
#endif
|
||||
@ -828,7 +827,7 @@ void MixerBoardScrolledWindow::OnMouseEvent(wxMouseEvent& event)
|
||||
//v Even when I implement MixerBoard::OnMouseEvent and call event.Skip()
|
||||
// here, MixerBoard::OnMouseEvent never gets called.
|
||||
// So, added mProject to MixerBoardScrolledWindow and just directly do what's needed here.
|
||||
mProject->SelectNone();
|
||||
SelectActions::SelectNone( *mProject );
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
@ -1344,8 +1343,11 @@ void MixerBoard::OnTimer(wxCommandEvent &event)
|
||||
// audacityAudioCallback where it calls gAudioIO->mOutputMeter->UpdateDisplay().
|
||||
if (mProject->IsAudioActive())
|
||||
{
|
||||
UpdateMeters(gAudioIO->GetStreamTime(),
|
||||
(mProject->mLastPlayMode == PlayMode::loopedPlay));
|
||||
UpdateMeters(
|
||||
gAudioIO->GetStreamTime(),
|
||||
(mProject->GetControlToolBar()->GetLastPlayMode()
|
||||
== PlayMode::loopedPlay)
|
||||
);
|
||||
}
|
||||
|
||||
// Let other listeners get the notification
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "widgets/ASlider.h" // to inherit
|
||||
#include "commands/CommandManagerWindowClasses.h"
|
||||
|
||||
#include "Prefs.h"
|
||||
|
||||
class wxArrayString;
|
||||
class wxBitmapButton;
|
||||
class wxImage;
|
||||
@ -188,7 +190,7 @@ public:
|
||||
class MixerBoardFrame;
|
||||
class TrackList;
|
||||
|
||||
class MixerBoard final : public wxWindow
|
||||
class MixerBoard final : public wxWindow, private PrefsListener
|
||||
{
|
||||
friend class MixerBoardFrame;
|
||||
|
||||
@ -198,7 +200,7 @@ public:
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize);
|
||||
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
|
||||
// Add clusters for any tracks we're not yet showing.
|
||||
// Update pointers for tracks we're aleady showing.
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "AColor.h"
|
||||
#include "DirManager.h"
|
||||
#include "Prefs.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectFileIORegistry.h"
|
||||
|
||||
#include "InconsistencyException.h"
|
||||
|
||||
@ -102,6 +104,15 @@ SONFNS(AutoSave)
|
||||
|
||||
|
||||
|
||||
static ProjectFileIORegistry::Entry registerFactory{
|
||||
wxT( "notetrack" ),
|
||||
[]( AudacityProject &project ){
|
||||
auto &trackFactory = *project.GetTrackFactory();
|
||||
auto &tracks = *project.GetTracks();
|
||||
return tracks.Add(trackFactory.NewNoteTrack());
|
||||
}
|
||||
};
|
||||
|
||||
NoteTrack::Holder TrackFactory::NewNoteTrack()
|
||||
{
|
||||
return std::make_shared<NoteTrack>(mDirManager);
|
||||
|
@ -69,6 +69,33 @@ std::unique_ptr<AudacityPrefs> ugPrefs {};
|
||||
AudacityPrefs *gPrefs = NULL;
|
||||
int gMenusDirty = 0;
|
||||
|
||||
wxDEFINE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent);
|
||||
|
||||
PrefsListener::PrefsListener()
|
||||
{
|
||||
wxTheApp->Bind(EVT_PREFS_UPDATE, &PrefsListener::OnEvent, this);
|
||||
}
|
||||
|
||||
PrefsListener::~PrefsListener()
|
||||
{
|
||||
// Explicit unbinding is needed because this is not a wxEvtHandler
|
||||
wxTheApp->Unbind(EVT_PREFS_UPDATE, &PrefsListener::OnEvent, this);
|
||||
}
|
||||
|
||||
void PrefsListener::UpdateSelectedPrefs( int )
|
||||
{
|
||||
}
|
||||
|
||||
void PrefsListener::OnEvent( wxCommandEvent &evt )
|
||||
{
|
||||
evt.Skip();
|
||||
auto id = evt.GetId();
|
||||
if (id <= 0)
|
||||
UpdatePrefs();
|
||||
else
|
||||
UpdateSelectedPrefs( id );
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Copy one entry from one wxConfig object to another
|
||||
static void CopyEntry(wxString path, wxConfigBase *src, wxConfigBase *dst, wxString entry)
|
||||
|
26
src/Prefs.h
26
src/Prefs.h
@ -34,6 +34,7 @@
|
||||
#include "../include/audacity/ComponentInterface.h"
|
||||
|
||||
#include <wx/fileconf.h> // to inherit wxFileConfig
|
||||
#include <wx/event.h> // to declare custom event types
|
||||
|
||||
void InitPreferences();
|
||||
void FinishPreferences();
|
||||
@ -159,4 +160,29 @@ private:
|
||||
const wxString mOldKey;
|
||||
};
|
||||
|
||||
// An event emitted by the application when the Preference dialog commits
|
||||
// changes
|
||||
wxDECLARE_EVENT(EVT_PREFS_UPDATE, wxCommandEvent);
|
||||
|
||||
// Invoke UpdatePrefs() when Preference dialog commits changes.
|
||||
class PrefsListener
|
||||
{
|
||||
public:
|
||||
PrefsListener();
|
||||
virtual ~PrefsListener();
|
||||
|
||||
// Called when all preferences should be updated.
|
||||
virtual void UpdatePrefs() = 0;
|
||||
|
||||
protected:
|
||||
// Called when only selected preferences are to be updated.
|
||||
// id is some value generated by wxNewId() that identifies the portion
|
||||
// of preferences.
|
||||
// Default function does nothing.
|
||||
virtual void UpdateSelectedPrefs( int id );
|
||||
|
||||
private:
|
||||
void OnEvent(wxCommandEvent&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
467
src/Project.cpp
467
src/Project.cpp
@ -51,6 +51,8 @@ scroll information. It also has some status flags.
|
||||
#include "Audacity.h" // for USE_* macros
|
||||
#include "Project.h"
|
||||
|
||||
#include "ProjectFileIORegistry.h"
|
||||
|
||||
#include "Experimental.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -583,6 +585,20 @@ private:
|
||||
#endif
|
||||
|
||||
|
||||
XMLTagHandler *
|
||||
AudacityProject::ImportHandlerFactory( AudacityProject &project ) {
|
||||
auto &ptr = project.mImportXMLTagHandler;
|
||||
if (!ptr)
|
||||
ptr =
|
||||
std::make_unique<ImportXMLTagHandler>( &project );
|
||||
return ptr.get();
|
||||
}
|
||||
|
||||
ProjectFileIORegistry::Entry
|
||||
AudacityProject::sImportHandlerFactory{
|
||||
wxT("import"), ImportHandlerFactory
|
||||
};
|
||||
|
||||
bool ImportXMLTagHandler::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
||||
{
|
||||
if (wxStrcmp(tag, wxT("import")) || attrs==NULL || (*attrs)==NULL || wxStrcmp(*attrs++, wxT("filename")))
|
||||
@ -1045,9 +1061,15 @@ enum {
|
||||
|
||||
HSBarID,
|
||||
VSBarID,
|
||||
TrackPanelID
|
||||
|
||||
NextID,
|
||||
};
|
||||
|
||||
int AudacityProject::NextWindowID()
|
||||
{
|
||||
return mNextWindowID++;
|
||||
}
|
||||
|
||||
|
||||
// PRL: This event type definition used to be in AudacityApp.h, which created
|
||||
// a bad compilation dependency. The event was never emitted anywhere. I
|
||||
@ -1076,8 +1098,6 @@ BEGIN_EVENT_TABLE(AudacityProject, wxFrame)
|
||||
EVT_COMMAND(wxID_ANY, EVT_OPEN_AUDIO_FILE, AudacityProject::OnOpenAudioFile)
|
||||
EVT_COMMAND(wxID_ANY, EVT_TOOLBAR_UPDATED, AudacityProject::OnToolBarUpdate)
|
||||
//mchinen:multithreaded calls - may not be threadsafe with CommandEvent: may have to change.
|
||||
EVT_COMMAND(wxID_ANY, EVT_ODTASK_UPDATE, AudacityProject::OnODTaskUpdate)
|
||||
EVT_COMMAND(wxID_ANY, EVT_ODTASK_COMPLETE, AudacityProject::OnODTaskComplete)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
@ -1100,6 +1120,10 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
mUndoManager(std::make_unique<UndoManager>())
|
||||
, mCommandManager( std::make_unique<CommandManager>() )
|
||||
{
|
||||
auto &window = *this;
|
||||
|
||||
mNextWindowID = NextID;
|
||||
|
||||
if (!gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleRate"), &mRate, AudioIO::GetOptimalSupportedSampleRate())) {
|
||||
// The default given above can vary with host/devices. So unless there is an entry for
|
||||
// the default sample rate in audacity.cfg, Audacity can open with a rate which is different
|
||||
@ -1150,8 +1174,6 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
|
||||
mMenuManager = std::make_unique<MenuManager>();
|
||||
|
||||
UpdatePrefs();
|
||||
|
||||
mLockPlayRegion = false;
|
||||
|
||||
// Make sure valgrind sees mIsSyncLocked is initialized, even
|
||||
@ -1199,7 +1221,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
//
|
||||
// Create the horizontal ruler
|
||||
//
|
||||
mRuler = safenew AdornedRulerPanel( this, mTopPanel,
|
||||
mRuler = safenew AdornedRulerPanel( this, window.GetTopPanel(),
|
||||
wxID_ANY,
|
||||
wxDefaultPosition,
|
||||
wxSize( -1, AdornedRulerPanel::GetRulerHeight(false) ),
|
||||
@ -1246,6 +1268,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
pPage->SetBackgroundColour(theTheme.Colour( clrMedium ));
|
||||
#endif
|
||||
|
||||
mMainPage = pPage;
|
||||
|
||||
{
|
||||
auto ubs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
ubs->Add(mToolManager->GetTopDock(), 0, wxEXPAND | wxALIGN_TOP);
|
||||
@ -1265,17 +1289,18 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
}
|
||||
bs->Layout();
|
||||
|
||||
// The right hand side translates to NEW TrackPanel(...) in normal
|
||||
// Audacity without additional DLLs.
|
||||
mTrackPanel = TrackPanel::FactoryFunction(pPage,
|
||||
TrackPanelID,
|
||||
{
|
||||
auto mainPage = window.GetMainPage();
|
||||
wxASSERT( mainPage ); // to justify safenew
|
||||
mTrackPanel = safenew TrackPanel(mainPage,
|
||||
window.NextWindowID(),
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
mTracks,
|
||||
&mViewInfo,
|
||||
this,
|
||||
mRuler);
|
||||
mTrackPanel->UpdatePrefs();
|
||||
}
|
||||
|
||||
mCursorOverlay = std::make_shared<EditCursorOverlay>(this);
|
||||
|
||||
@ -1294,7 +1319,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
&ViewInfo::OnTimer,
|
||||
&mViewInfo);
|
||||
|
||||
// Add the overlays, in the sequence in which they will be painted
|
||||
// Add the overlays
|
||||
mTrackPanel->AddOverlay( mIndicatorOverlay );
|
||||
mTrackPanel->AddOverlay( mCursorOverlay );
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
@ -1413,6 +1438,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
mTimer = std::make_unique<wxTimer>(this, AudacityProjectTimerID);
|
||||
RestartTimer();
|
||||
|
||||
UpdatePrefs();
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
// We can import now, so become a drag target
|
||||
// SetDropTarget(safenew AudacityDropTarget(this));
|
||||
@ -1422,10 +1449,6 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
mTrackPanel->SetDropTarget(safenew DropTarget(this));
|
||||
#endif
|
||||
|
||||
wxTheApp->Bind(EVT_AUDIOIO_CAPTURE,
|
||||
&AudacityProject::OnCapture,
|
||||
this);
|
||||
|
||||
wxTheApp->Bind(EVT_THEME_CHANGE, &AudacityProject::OnThemeChange, this);
|
||||
|
||||
#ifdef EXPERIMENTAL_DA2
|
||||
@ -1474,7 +1497,6 @@ void AudacityProject::UpdatePrefsVariables()
|
||||
{
|
||||
gPrefs->Read(wxT("/AudioFiles/ShowId3Dialog"), &mShowId3Dialog, true);
|
||||
gPrefs->Read(wxT("/AudioFiles/NormalizeOnLoad"),&mNormalizeOnLoad, false);
|
||||
gPrefs->Read(wxT("/GUI/AutoScroll"), &mViewInfo.bUpdateTrackIndicator, true);
|
||||
gPrefs->Read(wxT("/GUI/EmptyCanBeDirty"), &mEmptyCanBeDirty, true );
|
||||
gPrefs->Read(wxT("/GUI/ShowSplashScreen"), &mShowSplashScreen, true);
|
||||
gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Simple"));
|
||||
@ -1508,38 +1530,6 @@ void AudacityProject::UpdatePrefs()
|
||||
UpdatePrefsVariables();
|
||||
|
||||
SetProjectTitle();
|
||||
|
||||
{
|
||||
ObjectFactorySetLocker locker;
|
||||
for( const auto &pObject : mAttachedObjects )
|
||||
pObject->UpdatePrefs();
|
||||
}
|
||||
|
||||
GetMenuManager(*this).UpdatePrefs();
|
||||
|
||||
if (mTrackPanel) {
|
||||
mTrackPanel->UpdatePrefs();
|
||||
}
|
||||
if (mMixerBoard)
|
||||
mMixerBoard->UpdatePrefs();
|
||||
|
||||
if (mToolManager) {
|
||||
mToolManager->UpdatePrefs();
|
||||
}
|
||||
|
||||
if (mRuler) {
|
||||
mRuler->UpdatePrefs();
|
||||
}
|
||||
}
|
||||
|
||||
void AudacityProject::SetMissingAliasFileDialog(wxDialog *dialog)
|
||||
{
|
||||
mMissingAliasFilesWarningDialog = dialog;
|
||||
}
|
||||
|
||||
wxDialog *AudacityProject::GetMissingAliasFileDialog()
|
||||
{
|
||||
return mMissingAliasFilesWarningDialog;
|
||||
}
|
||||
|
||||
void AudacityProject::RedrawProject(const bool bForceWaveTracks /*= false*/)
|
||||
@ -1559,16 +1549,6 @@ void AudacityProject::RefreshCursor()
|
||||
mTrackPanel->HandleCursorForPresentMouseState();
|
||||
}
|
||||
|
||||
void AudacityProject::OnCapture(wxCommandEvent& evt)
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
if (evt.GetInt() != 0)
|
||||
mIsCapturing = true;
|
||||
else
|
||||
mIsCapturing = false;
|
||||
}
|
||||
|
||||
void AudacityProject::OnThemeChange(wxCommandEvent& evt)
|
||||
{
|
||||
evt.Skip();
|
||||
@ -1582,7 +1562,6 @@ void AudacityProject::OnThemeChange(wxCommandEvent& evt)
|
||||
GetRulerPanel()->ReCreateButtons();
|
||||
}
|
||||
|
||||
|
||||
const std::shared_ptr<DirManager> &AudacityProject::GetDirManager()
|
||||
{
|
||||
return mDirManager;
|
||||
@ -1614,7 +1593,12 @@ bool AudacityProject::IsAudioActive() const
|
||||
gAudioIO->IsStreamActive(GetAudioIOToken());
|
||||
}
|
||||
|
||||
const Tags *AudacityProject::GetTags()
|
||||
Tags *AudacityProject::GetTags()
|
||||
{
|
||||
return mTags.get();
|
||||
}
|
||||
|
||||
const Tags *AudacityProject::GetTags() const
|
||||
{
|
||||
return mTags.get();
|
||||
}
|
||||
@ -2371,22 +2355,6 @@ void AudacityProject::OnToolBarUpdate(wxCommandEvent & event)
|
||||
event.Skip(false); /* No need to propagate any further */
|
||||
}
|
||||
|
||||
///Handles the redrawing necessary for tasks as they partially update in the background.
|
||||
void AudacityProject::OnODTaskUpdate(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
//todo: add track data to the event - check to see if the project contains it before redrawing.
|
||||
if(mTrackPanel)
|
||||
mTrackPanel->Refresh(false);
|
||||
|
||||
}
|
||||
|
||||
//redraws the task and does other book keeping after the task is complete.
|
||||
void AudacityProject::OnODTaskComplete(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
if(mTrackPanel)
|
||||
mTrackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
void AudacityProject::OnScroll(wxScrollEvent & WXUNUSED(event))
|
||||
{
|
||||
const wxInt64 offset = PixelWidthBeforeTime(0.0);
|
||||
@ -2484,7 +2452,7 @@ void AudacityProject::OnActivate(wxActivateEvent & event)
|
||||
{
|
||||
// Activate events can fire during window teardown, so just
|
||||
// ignore them.
|
||||
if (mIsDeleting) {
|
||||
if (IsBeingDeleted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2570,12 +2538,16 @@ public:
|
||||
// and/or attempts to DELETE objects twice.
|
||||
void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
||||
{
|
||||
auto &project = *this;
|
||||
auto &projectFileIO = project;
|
||||
auto &window = project;
|
||||
|
||||
// We are called for the wxEVT_CLOSE_WINDOW, wxEVT_END_SESSION, and
|
||||
// wxEVT_QUERY_END_SESSION, so we have to protect against multiple
|
||||
// entries. This is a hack until the whole application termination
|
||||
// process can be reviewed and reworked. (See bug #964 for ways
|
||||
// to exercise the bug that instigated this hack.)
|
||||
if (mIsBeingDeleted)
|
||||
if (window.IsBeingDeleted())
|
||||
{
|
||||
event.Skip();
|
||||
return;
|
||||
@ -2673,7 +2645,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
||||
// its size change.
|
||||
AllProjects::SaveWindowSize();
|
||||
|
||||
mIsDeleting = true;
|
||||
window.SetIsBeingDeleted();
|
||||
|
||||
// Mac: we never quit as the result of a close.
|
||||
// Other systems: we quit only when the close is the result of an external
|
||||
@ -2696,17 +2668,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
||||
// TODO: Is there a Mac issue here??
|
||||
// SetMenuBar(NULL);
|
||||
|
||||
// Lock all blocks in all tracks of the last saved version, so that
|
||||
// the blockfiles aren't deleted on disk when we DELETE the blockfiles
|
||||
// in memory. After it's locked, DELETE the data structure so that
|
||||
// there's no memory leak.
|
||||
if (mLastSavedTracks) {
|
||||
for (auto wt : mLastSavedTracks->Any<WaveTrack>())
|
||||
wt->CloseLock();
|
||||
|
||||
mLastSavedTracks->Clear(); // sends an event
|
||||
mLastSavedTracks.reset();
|
||||
}
|
||||
projectFileIO.CloseLock();
|
||||
|
||||
// Get rid of the history window
|
||||
// LL: Destroy it before the TrackPanel and ToolBars since they
|
||||
@ -2744,8 +2706,6 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
||||
|
||||
mTags.reset();
|
||||
|
||||
mImportXMLTagHandler.reset();
|
||||
|
||||
// Delete all the tracks to free up memory and DirManager references.
|
||||
mTracks->Clear();
|
||||
mTracks.reset();
|
||||
@ -2809,9 +2769,6 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
||||
// Destroys this
|
||||
pSelf.reset();
|
||||
mRuler = nullptr;
|
||||
|
||||
mIsBeingDeleted = true;
|
||||
|
||||
}
|
||||
|
||||
void AudacityProject::OnOpenAudioFile(wxCommandEvent & event)
|
||||
@ -3046,6 +3003,106 @@ AudacityProject *AudacityProject::OpenProject(
|
||||
return pProject;
|
||||
}
|
||||
|
||||
auto AudacityProject::ReadProjectFile( const FilePath &fileName )
|
||||
-> ReadProjectResults
|
||||
{
|
||||
mFileName = fileName;
|
||||
mbLoadedFromAup = true;
|
||||
|
||||
mRecoveryAutoSaveDataDir = wxT("");
|
||||
mIsRecovered = false;
|
||||
|
||||
SetProjectTitle();
|
||||
|
||||
const wxString autoSaveExt = wxT("autosave");
|
||||
if ( wxFileNameWrapper{ mFileName }.GetExt() == autoSaveExt )
|
||||
{
|
||||
AutoSaveFile asf;
|
||||
if (!asf.Decode(fileName))
|
||||
{
|
||||
auto message = AutoSaveFile::FailureMessage( fileName );
|
||||
AudacityMessageBox(
|
||||
message,
|
||||
_("Error decoding file"),
|
||||
wxOK | wxCENTRE, this);
|
||||
// Important: Prevent deleting any temporary files!
|
||||
DirManager::SetDontDeleteTempFiles();
|
||||
return { true };
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Parse project file
|
||||
///
|
||||
|
||||
XMLFileReader xmlFile;
|
||||
|
||||
// 'Lossless copy' projects have dependencies. We need to always copy-in
|
||||
// these dependencies when converting to a normal project.
|
||||
wxString oldAction =
|
||||
gPrefs->Read(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
bool oldAsk =
|
||||
gPrefs->ReadBool(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), true);
|
||||
if (oldAction != wxT("copy"))
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
if (oldAsk)
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) false);
|
||||
gPrefs->Flush();
|
||||
|
||||
auto cleanup = finally( [&] {
|
||||
// and restore old settings if necessary.
|
||||
if (oldAction != wxT("copy"))
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), oldAction);
|
||||
if (oldAsk)
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) true);
|
||||
gPrefs->Flush();
|
||||
} );
|
||||
|
||||
bool bParseSuccess = xmlFile.Parse(this, fileName);
|
||||
|
||||
bool err = false;
|
||||
|
||||
if (bParseSuccess) {
|
||||
// By making a duplicate set of pointers to the existing blocks
|
||||
// on disk, we add one to their reference count, guaranteeing
|
||||
// that their reference counts will never reach zero and thus
|
||||
// the version saved on disk will be preserved until the
|
||||
// user selects Save().
|
||||
|
||||
mLastSavedTracks = TrackList::Create();
|
||||
|
||||
for (auto t : GetTracks()->Any()) {
|
||||
if (t->GetErrorOpening())
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Track %s had error reading clip values from project file."),
|
||||
t->GetName());
|
||||
err = true;
|
||||
}
|
||||
|
||||
err = ( !t->LinkConsistencyCheck() ) || err;
|
||||
|
||||
mLastSavedTracks->Add(t->Duplicate());
|
||||
}
|
||||
}
|
||||
|
||||
return { false, bParseSuccess, err, xmlFile.GetErrorStr() };
|
||||
}
|
||||
|
||||
XMLTagHandler *
|
||||
AudacityProject::RecordingRecoveryFactory( AudacityProject &project ) {
|
||||
auto &ptr = project.mRecordingRecoveryHandler;
|
||||
if (!ptr)
|
||||
ptr =
|
||||
std::make_unique<RecordingRecoveryHandler>( &project );
|
||||
return ptr.get();
|
||||
}
|
||||
|
||||
ProjectFileIORegistry::Entry
|
||||
AudacityProject::sRecoveryFactory{
|
||||
wxT("recordingrecovery"), RecordingRecoveryFactory
|
||||
};
|
||||
|
||||
// FIXME:? TRAP_ERR This should return a result that is checked.
|
||||
// See comment in AudacityApp::MRUOpen().
|
||||
void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
|
||||
@ -3160,85 +3217,23 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
|
||||
return;
|
||||
}
|
||||
|
||||
///
|
||||
/// Parse project file
|
||||
///
|
||||
|
||||
mFileName = fileName;
|
||||
mbLoadedFromAup = true;
|
||||
|
||||
mRecoveryAutoSaveDataDir = wxT("");
|
||||
mIsRecovered = false;
|
||||
|
||||
SetProjectTitle();
|
||||
|
||||
const wxString autoSaveExt = wxT(".autosave");
|
||||
if (mFileName.length() >= autoSaveExt.length() &&
|
||||
mFileName.Right(autoSaveExt.length()) == autoSaveExt)
|
||||
{
|
||||
AutoSaveFile asf;
|
||||
if (!asf.Decode(fileName))
|
||||
{
|
||||
auto message = AutoSaveFile::FailureMessage( fileName );
|
||||
AudacityMessageBox(
|
||||
message,
|
||||
_("Error decoding file"),
|
||||
wxOK | wxCENTRE, this);
|
||||
// Important: Prevent deleting any temporary files!
|
||||
DirManager::SetDontDeleteTempFiles();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
XMLFileReader xmlFile;
|
||||
|
||||
// 'Lossless copy' projects have dependencies. We need to always copy-in
|
||||
// these dependencies when converting to a normal project.
|
||||
wxString oldAction = gPrefs->Read(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
bool oldAsk = gPrefs->Read(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), true)?true:false;
|
||||
if (oldAction != wxT("copy"))
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), wxT("copy"));
|
||||
if (oldAsk)
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) false);
|
||||
gPrefs->Flush();
|
||||
|
||||
bool bParseSuccess = xmlFile.Parse(this, fileName);
|
||||
|
||||
// and restore old settings if necessary.
|
||||
if (oldAction != wxT("copy"))
|
||||
gPrefs->Write(wxT("/FileFormats/CopyOrEditUncompressedData"), oldAction);
|
||||
if (oldAsk)
|
||||
gPrefs->Write(wxT("/Warnings/CopyOrEditUncompressedDataAsk"), (long) true);
|
||||
gPrefs->Flush();
|
||||
|
||||
// Clean up now unused recording recovery handler if any
|
||||
// The handlers may be created during ReadProjectFile and are not needed
|
||||
// after this function exits.
|
||||
auto cleanupHandlers = finally( [this]{
|
||||
mImportXMLTagHandler.reset();
|
||||
mRecordingRecoveryHandler.reset();
|
||||
} );
|
||||
|
||||
bool err = false;
|
||||
auto results = ReadProjectFile( fileName );
|
||||
|
||||
if ( results.decodeError )
|
||||
return;
|
||||
|
||||
const bool bParseSuccess = results.parseSuccess;
|
||||
const wxString &errorStr = results.errorString;
|
||||
const bool err = results.trackError;
|
||||
|
||||
if (bParseSuccess) {
|
||||
// By making a duplicate set of pointers to the existing blocks
|
||||
// on disk, we add one to their reference count, guaranteeing
|
||||
// that their reference counts will never reach zero and thus
|
||||
// the version saved on disk will be preserved until the
|
||||
// user selects Save().
|
||||
|
||||
mLastSavedTracks = TrackList::Create();
|
||||
|
||||
for (auto t : GetTracks()->Any()) {
|
||||
if (t->GetErrorOpening())
|
||||
{
|
||||
wxLogWarning(
|
||||
wxT("Track %s had error reading clip values from project file."),
|
||||
t->GetName());
|
||||
err = true;
|
||||
}
|
||||
|
||||
err = ( !t->LinkConsistencyCheck() ) || err;
|
||||
|
||||
mLastSavedTracks->Add(t->Duplicate());
|
||||
}
|
||||
|
||||
InitialState();
|
||||
mTrackPanel->SetFocusedTrack(*GetTracks()->Any().begin());
|
||||
HandleResize();
|
||||
@ -3259,9 +3254,6 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
|
||||
ODManager::UnmarkLoadedODFlag();
|
||||
|
||||
if (! closed ) {
|
||||
// Shouldn't need it any more.
|
||||
mImportXMLTagHandler.reset();
|
||||
|
||||
if ( bParseSuccess ) {
|
||||
// This is a no-fail:
|
||||
GetDirManager()->FillBlockfilesCache();
|
||||
@ -3363,9 +3355,8 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
|
||||
mFileName = wxT("");
|
||||
SetProjectTitle();
|
||||
|
||||
wxLogError(wxT("Could not parse file \"%s\". \nError: %s"), fileName, xmlFile.GetErrorStr());
|
||||
wxLogError(wxT("Could not parse file \"%s\". \nError: %s"), fileName, errorStr);
|
||||
|
||||
wxString errorStr = xmlFile.GetErrorStr();
|
||||
wxString url = wxT("FAQ:Errors_on_opening_or_recovering_an_Audacity_project");
|
||||
|
||||
// Certain errors have dedicated help.
|
||||
@ -3627,8 +3618,6 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
||||
NumericConverter::LookupFormat( NumericConverter::BANDWIDTH, value ) );
|
||||
} // while
|
||||
|
||||
mViewInfo.UpdatePrefs();
|
||||
|
||||
if (longVpos != 0) {
|
||||
// PRL: It seems this must happen after SetSnapTo
|
||||
mViewInfo.vpos = longVpos;
|
||||
@ -3712,45 +3701,11 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
||||
|
||||
XMLTagHandler *AudacityProject::HandleXMLChild(const wxChar *tag)
|
||||
{
|
||||
if (!wxStrcmp(tag, wxT("tags"))) {
|
||||
return mTags.get();
|
||||
}
|
||||
auto fn = ProjectFileIORegistry::Lookup( tag );
|
||||
if (fn)
|
||||
return fn( *this );
|
||||
|
||||
// Note that TrackList::Add includes assignment of unique in-session TrackId
|
||||
// to a reloaded track, though no promise that it equals the id it originally
|
||||
// had
|
||||
|
||||
if (!wxStrcmp(tag, wxT("wavetrack"))) {
|
||||
return mTracks->Add(mTrackFactory->NewWaveTrack());
|
||||
}
|
||||
|
||||
#ifdef USE_MIDI
|
||||
if (!wxStrcmp(tag, wxT("notetrack"))) {
|
||||
return mTracks->Add(mTrackFactory->NewNoteTrack());
|
||||
}
|
||||
#endif // USE_MIDI
|
||||
|
||||
if (!wxStrcmp(tag, wxT("labeltrack"))) {
|
||||
return mTracks->Add(mTrackFactory->NewLabelTrack());
|
||||
}
|
||||
|
||||
if (!wxStrcmp(tag, wxT("timetrack"))) {
|
||||
return mTracks->Add(mTrackFactory->NewTimeTrack());
|
||||
}
|
||||
|
||||
if (!wxStrcmp(tag, wxT("recordingrecovery"))) {
|
||||
if (!mRecordingRecoveryHandler)
|
||||
mRecordingRecoveryHandler = std::make_unique<RecordingRecoveryHandler>(this);
|
||||
return mRecordingRecoveryHandler.get();
|
||||
}
|
||||
|
||||
if (!wxStrcmp(tag, wxT("import"))) {
|
||||
if (!mImportXMLTagHandler)
|
||||
mImportXMLTagHandler = std::make_unique<ImportXMLTagHandler>(this);
|
||||
return mImportXMLTagHandler.get();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AudacityProject::WriteXMLHeader(XMLWriter &xmlFile) const
|
||||
@ -4275,9 +4230,10 @@ std::vector< std::shared_ptr< Track > >
|
||||
AudacityProject::AddImportedTracks(const FilePath &fileName,
|
||||
TrackHolders &&newTracks)
|
||||
{
|
||||
auto &project = *this;
|
||||
std::vector< std::shared_ptr< Track > > results;
|
||||
|
||||
SelectNone();
|
||||
SelectActions::SelectNone( project );
|
||||
|
||||
bool initiallyEmpty = mTracks->empty();
|
||||
double newRate = 0;
|
||||
@ -4387,6 +4343,7 @@ void AudacityProject::ZoomAfterImport(Track *pTrack)
|
||||
// If pNewTrackList is passed in non-NULL, it gets filled with the pointers to NEW tracks.
|
||||
bool AudacityProject::Import(const FilePath &fileName, WaveTrackArray* pTrackArray /*= NULL*/)
|
||||
{
|
||||
auto &project = *this;
|
||||
TrackHolders newTracks;
|
||||
wxString errorMessage;
|
||||
|
||||
@ -4441,9 +4398,9 @@ bool AudacityProject::Import(const FilePath &fileName, WaveTrackArray* pTrackArr
|
||||
int mode = gPrefs->Read(wxT("/AudioFiles/NormalizeOnLoad"), 0L);
|
||||
if (mode == 1) {
|
||||
//TODO: All we want is a SelectAll()
|
||||
SelectNone();
|
||||
SelectAllIfNone();
|
||||
const CommandContext context( *this);
|
||||
SelectActions::SelectNone( project );
|
||||
SelectActions::SelectAllIfNone( project );
|
||||
const CommandContext context( project );
|
||||
PluginActions::DoEffect(
|
||||
EffectManager::Get().GetEffectByIdentifier(wxT("Normalize")),
|
||||
context,
|
||||
@ -5347,14 +5304,6 @@ void AudacityProject::SetSyncLock(bool flag)
|
||||
}
|
||||
}
|
||||
|
||||
bool AudacityProject::ExportFromTimerRecording(wxFileName fnFile, int iFormat, int iSubFormat, int iFilterIndex)
|
||||
{
|
||||
Exporter e;
|
||||
|
||||
MissingAliasFilesDialog::SetShouldShow(true);
|
||||
return e.ProcessFromTimerRecording(this, false, 0.0, mTracks->GetEndTime(), fnFile, iFormat, iSubFormat, iFilterIndex);
|
||||
}
|
||||
|
||||
int AudacityProject::GetOpenProjectCount() {
|
||||
return gAudacityProjects.size();
|
||||
}
|
||||
@ -5368,32 +5317,35 @@ bool AudacityProject::IsProjectSaved() {
|
||||
|
||||
// This is done to empty out the tracks, but without creating a new project.
|
||||
void AudacityProject::ResetProjectToEmpty() {
|
||||
SelectActions::DoSelectAll(*this);
|
||||
TrackActions::DoRemoveTracks(*this);
|
||||
auto &project = *this;
|
||||
auto &projectFileIO = project;
|
||||
|
||||
SelectActions::DoSelectAll( project );
|
||||
TrackActions::DoRemoveTracks( project );
|
||||
// A new DirManager.
|
||||
mDirManager = DirManager::Create();
|
||||
mTrackFactory.reset(safenew TrackFactory{ mDirManager, &mViewInfo });
|
||||
|
||||
projectFileIO.ResetProjectFileIO();
|
||||
|
||||
mDirty = false;
|
||||
GetUndoManager()->ClearStates();
|
||||
}
|
||||
|
||||
void AudacityProject::ResetProjectFileIO()
|
||||
{
|
||||
// mLastSavedTrack code copied from OnCloseWindow.
|
||||
// Lock all blocks in all tracks of the last saved version, so that
|
||||
// the blockfiles aren't deleted on disk when we DELETE the blockfiles
|
||||
// in memory. After it's locked, DELETE the data structure so that
|
||||
// there's no memory leak.
|
||||
if (mLastSavedTracks) {
|
||||
for (auto t : mLastSavedTracks->Any<WaveTrack>())
|
||||
t->CloseLock();
|
||||
|
||||
mLastSavedTracks->Clear(); // sends an event
|
||||
mLastSavedTracks.reset();
|
||||
}
|
||||
CloseLock();
|
||||
|
||||
//mLastSavedTracks = TrackList::Create();
|
||||
mFileName = "";
|
||||
mIsRecovered = false;
|
||||
mbLoadedFromAup = false;
|
||||
SetProjectTitle();
|
||||
mDirty = false;
|
||||
GetUndoManager()->ClearStates();
|
||||
}
|
||||
|
||||
bool AudacityProject::SaveFromTimerRecording(wxFileName fnFile) {
|
||||
@ -5561,10 +5513,8 @@ LyricsWindow* AudacityProject::GetLyricsWindow(bool create)
|
||||
|
||||
MixerBoardFrame* AudacityProject::GetMixerBoardFrame(bool create)
|
||||
{
|
||||
if (create && !mMixerBoardFrame) {
|
||||
if (create && !mMixerBoardFrame)
|
||||
mMixerBoardFrame = safenew MixerBoardFrame{ this };
|
||||
mMixerBoard = mMixerBoardFrame->mMixerBoard;
|
||||
}
|
||||
return mMixerBoardFrame;
|
||||
}
|
||||
|
||||
@ -5610,14 +5560,6 @@ ContrastDialog *AudacityProject::GetContrastDialog(bool create)
|
||||
return mContrastDialog.get();
|
||||
}
|
||||
|
||||
void AudacityProject::SelectNone()
|
||||
{
|
||||
for (auto t : GetTracks()->Any())
|
||||
t->SetSelected(false);
|
||||
|
||||
mTrackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
void AudacityProject::ZoomInByFactor( double ZoomFactor )
|
||||
{
|
||||
// LLL: Handling positioning differently when audio is
|
||||
@ -5708,20 +5650,17 @@ void AudacityProject::ZoomOutByFactor( double ZoomFactor )
|
||||
TP_ScrollWindow(newh);
|
||||
}
|
||||
|
||||
// Select the full time range, if no
|
||||
// time range is selected.
|
||||
void AudacityProject::SelectAllIfNone()
|
||||
void AudacityProject::CloseLock()
|
||||
{
|
||||
auto flags = GetMenuManager(*this).GetUpdateFlags(*this);
|
||||
if(!(flags & TracksSelectedFlag) ||
|
||||
(mViewInfo.selectedRegion.isPoint()))
|
||||
SelectActions::DoSelectAllAudio(*this);
|
||||
}
|
||||
// Lock all blocks in all tracks of the last saved version, so that
|
||||
// the blockfiles aren't deleted on disk when we DELETE the blockfiles
|
||||
// in memory. After it's locked, DELETE the data structure so that
|
||||
// there's no memory leak.
|
||||
if (mLastSavedTracks) {
|
||||
for (auto wt : mLastSavedTracks->Any<WaveTrack>())
|
||||
wt->CloseLock();
|
||||
|
||||
// Stop playing or recording, if paused.
|
||||
void AudacityProject::StopIfPaused()
|
||||
{
|
||||
auto flags = GetMenuManager(*this).GetUpdateFlags(*this);
|
||||
if( flags & PausedFlag )
|
||||
TransportActions::DoStop(*this);
|
||||
mLastSavedTracks->Clear();
|
||||
mLastSavedTracks.reset();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "Experimental.h"
|
||||
|
||||
#include "Track.h"
|
||||
#include "Prefs.h"
|
||||
#include "SelectionState.h"
|
||||
#include "ViewInfo.h"
|
||||
#include "commands/CommandManagerWindowClasses.h"
|
||||
@ -56,6 +57,7 @@ class Importer;
|
||||
class ODLock;
|
||||
class Overlay;
|
||||
class RecordingRecoveryHandler;
|
||||
namespace ProjectFileIORegistry{ struct Entry; }
|
||||
class TrackList;
|
||||
class Tags;
|
||||
|
||||
@ -115,12 +117,6 @@ using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
|
||||
extern AProjectArray gAudacityProjects;
|
||||
|
||||
|
||||
enum class PlayMode : int {
|
||||
normalPlay,
|
||||
oneSecondPlay, // Disables auto-scrolling
|
||||
loopedPlay // Disables auto-scrolling
|
||||
};
|
||||
|
||||
enum StatusBarField {
|
||||
stateStatusBarField = 1,
|
||||
mainStatusBarField = 2,
|
||||
@ -176,21 +172,23 @@ class WaveTrack;
|
||||
|
||||
class MenuManager;
|
||||
|
||||
class PrefsListener;
|
||||
|
||||
class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
||||
public TrackPanelListener,
|
||||
public SelectionBarListener,
|
||||
public SpectralSelectionBarListener,
|
||||
public XMLTagHandler,
|
||||
public AudioIOListener
|
||||
public AudioIOListener,
|
||||
private PrefsListener
|
||||
{
|
||||
public:
|
||||
AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
const wxPoint & pos, const wxSize & size);
|
||||
virtual ~AudacityProject();
|
||||
|
||||
using AttachedObject = PrefsListener;
|
||||
// Next available ID for sub-windows
|
||||
int NextWindowID();
|
||||
|
||||
using AttachedObject = wxObject;
|
||||
using AttachedObjectFactory =
|
||||
std::function< std::unique_ptr<AttachedObject>() >;
|
||||
|
||||
@ -233,7 +231,8 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
||||
const std::shared_ptr<DirManager> &GetDirManager();
|
||||
TrackFactory *GetTrackFactory();
|
||||
AdornedRulerPanel *GetRulerPanel();
|
||||
const Tags *GetTags();
|
||||
Tags *GetTags();
|
||||
const Tags *GetTags() const;
|
||||
void SetTags( const std::shared_ptr<Tags> &tags );
|
||||
int GetAudioIOToken() const;
|
||||
bool IsAudioActive() const;
|
||||
@ -282,6 +281,15 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
||||
AudacityProject *pProject,
|
||||
const FilePath &fileNameArg, bool addtohistory = true);
|
||||
|
||||
struct ReadProjectResults
|
||||
{
|
||||
bool decodeError;
|
||||
bool parseSuccess;
|
||||
bool trackError;
|
||||
wxString errorString;
|
||||
};
|
||||
ReadProjectResults ReadProjectFile( const FilePath &fileName );
|
||||
|
||||
void OpenFile(const FilePath &fileName, bool addtohistory = true);
|
||||
|
||||
private:
|
||||
@ -302,6 +310,8 @@ public:
|
||||
AddImportedTracks(const FilePath &fileName,
|
||||
TrackHolders &&newTracks);
|
||||
|
||||
void CloseLock();
|
||||
|
||||
bool Save();
|
||||
bool SaveAs(bool bWantSaveCopy = false, bool bLossless = false);
|
||||
bool SaveAs(const wxString & newFileName, bool bWantSaveCopy = false, bool addToHistory = true);
|
||||
@ -316,6 +326,7 @@ public:
|
||||
bool GetDirty() { return mDirty; }
|
||||
void SetProjectTitle( int number =-1);
|
||||
|
||||
wxWindow *GetMainPage() { return mMainPage; }
|
||||
wxPanel *GetTopPanel() { return mTopPanel; }
|
||||
TrackPanel * GetTrackPanel() {return mTrackPanel;}
|
||||
const TrackPanel * GetTrackPanel() const {return mTrackPanel;}
|
||||
@ -330,21 +341,12 @@ public:
|
||||
bool GetNormalizeOnLoad() { return mNormalizeOnLoad; } //lda
|
||||
void SetNormalizeOnLoad(bool flag) { mNormalizeOnLoad = flag; } //lda
|
||||
|
||||
/** \brief Sets the wxDialog that is being displayed
|
||||
* Used by the custom dialog warning constructor and destructor
|
||||
*/
|
||||
void SetMissingAliasFileDialog(wxDialog *dialog);
|
||||
|
||||
/** \brief returns a pointer to the wxDialog if it is displayed, NULL otherwise.
|
||||
*/
|
||||
wxDialog *GetMissingAliasFileDialog();
|
||||
|
||||
// Timer Record Auto Save/Export Routines
|
||||
bool SaveFromTimerRecording(wxFileName fnFile);
|
||||
bool ExportFromTimerRecording(wxFileName fnFile, int iFormat, int iSubFormat, int iFilterIndex);
|
||||
static int GetOpenProjectCount();
|
||||
bool IsProjectSaved();
|
||||
void ResetProjectToEmpty();
|
||||
void ResetProjectFileIO();
|
||||
|
||||
// Routine to estimate how many minutes of recording time are left on disk
|
||||
int GetEstimatedRecordingMinsLeftOnDisk(long lCaptureChannels = 0);
|
||||
@ -378,8 +380,6 @@ public:
|
||||
void OnTimer(wxTimerEvent & event);
|
||||
void OnToolBarUpdate(wxCommandEvent & event);
|
||||
void OnOpenAudioFile(wxCommandEvent & event);
|
||||
void OnODTaskUpdate(wxCommandEvent & event);
|
||||
void OnODTaskComplete(wxCommandEvent & event);
|
||||
|
||||
void HandleResize();
|
||||
void UpdateLayout();
|
||||
@ -391,13 +391,10 @@ public:
|
||||
int GetProjectNumber(){ return mProjectNo;};
|
||||
static int CountUnnamed();
|
||||
static void RefreshAllTitles(bool bShowProjectNumbers );
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
void UpdatePrefsVariables();
|
||||
void RedrawProject(const bool bForceWaveTracks = false);
|
||||
void RefreshCursor();
|
||||
void SelectNone();
|
||||
void SelectAllIfNone();
|
||||
void StopIfPaused();
|
||||
void Zoom(double level);
|
||||
void ZoomBy(double multiplier);
|
||||
void Rewind(bool shift);
|
||||
@ -521,7 +518,6 @@ public:
|
||||
|
||||
void WriteXMLHeader(XMLWriter &xmlFile) const;
|
||||
|
||||
PlayMode mLastPlayMode{ PlayMode::normalPlay };
|
||||
ViewInfo mViewInfo;
|
||||
|
||||
// Audio IO callback methods
|
||||
@ -540,7 +536,6 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void OnCapture(wxCommandEvent & evt);
|
||||
void OnThemeChange(wxCommandEvent & evt);
|
||||
void InitialState();
|
||||
|
||||
@ -613,6 +608,7 @@ private:
|
||||
TrackPanel *mTrackPanel{};
|
||||
SelectionState mSelectionState{};
|
||||
std::unique_ptr<TrackFactory> mTrackFactory{};
|
||||
wxWindow * mMainPage;
|
||||
wxPanel * mMainPanel;
|
||||
wxScrollBar *mHsbar;
|
||||
wxScrollBar *mVsbar;
|
||||
@ -621,6 +617,8 @@ public:
|
||||
wxScrollBar &GetVerticalScrollBar() { return *mVsbar; }
|
||||
|
||||
private:
|
||||
int mNextWindowID;
|
||||
|
||||
bool mAutoScrolling{ false };
|
||||
bool mActive{ true };
|
||||
bool mIconized;
|
||||
@ -629,14 +627,10 @@ private:
|
||||
HistoryWindow *mHistoryWindow{};
|
||||
LyricsWindow* mLyricsWindow{};
|
||||
MixerBoardFrame* mMixerBoardFrame{};
|
||||
MixerBoard* mMixerBoard{};
|
||||
|
||||
Destroy_ptr<FreqWindow> mFreqWindow;
|
||||
Destroy_ptr<ContrastDialog> mContrastDialog;
|
||||
|
||||
// dialog for missing alias warnings
|
||||
wxDialog *mMissingAliasFilesWarningDialog{};
|
||||
|
||||
bool mShownOnce{ false };
|
||||
|
||||
// Project owned meters
|
||||
@ -659,13 +653,6 @@ private:
|
||||
void SetTimerRecordCancelled(){mTimerRecordCanceled=true;}
|
||||
void ResetTimerRecordCancelled(){mTimerRecordCanceled=false;}
|
||||
|
||||
//sort method used by OnSortName and OnSortTime
|
||||
//currently only supported flags are kAudacitySortByName and kAudacitySortByName
|
||||
//in the future we might have 0x01 as sort ascending and we can bit or it
|
||||
#define kAudacitySortByTime (1 << 1)
|
||||
#define kAudacitySortByName (1 << 2)
|
||||
void SortTracks(int flags);
|
||||
|
||||
private:
|
||||
int mAudioIOToken{ -1 };
|
||||
|
||||
@ -677,6 +664,8 @@ private:
|
||||
|
||||
public:
|
||||
bool EmptyCanBeDirty() const { return mEmptyCanBeDirty; }
|
||||
bool IsBeingDeleted() const { return mIsDeleting; }
|
||||
void SetIsBeingDeleted() { mIsDeleting = true; }
|
||||
private:
|
||||
|
||||
bool mIsSyncLocked;
|
||||
@ -719,20 +708,6 @@ public:
|
||||
private:
|
||||
bool mbInitializingScrollbar{ false };
|
||||
|
||||
// Flag that we're recoding.
|
||||
bool mIsCapturing{ false };
|
||||
|
||||
public:
|
||||
bool IsCapturing() const { return mIsCapturing; }
|
||||
|
||||
private:
|
||||
|
||||
// See explanation in OnCloseWindow
|
||||
bool mIsBeingDeleted{ false };
|
||||
|
||||
// CommandManager needs to use private methods
|
||||
friend class CommandManager;
|
||||
|
||||
// TrackPanelOverlay objects
|
||||
std::shared_ptr<Overlay>
|
||||
mIndicatorOverlay, mCursorOverlay;
|
||||
@ -783,6 +758,12 @@ public:
|
||||
private:
|
||||
std::unique_ptr<PlaybackScroller> mPlaybackScroller;
|
||||
|
||||
// Declared in this class so that they can have access to private members
|
||||
static XMLTagHandler *RecordingRecoveryFactory( AudacityProject &project );
|
||||
static ProjectFileIORegistry::Entry sRecoveryFactory;
|
||||
static XMLTagHandler *ImportHandlerFactory( AudacityProject &project );
|
||||
static ProjectFileIORegistry::Entry sImportHandlerFactory;
|
||||
|
||||
public:
|
||||
PlaybackScroller &GetPlaybackScroller() { return *mPlaybackScroller; }
|
||||
std::shared_ptr<BackgroundCell> GetBackgroundCell() const
|
||||
|
44
src/ProjectFileIORegistry.cpp
Normal file
44
src/ProjectFileIORegistry.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
ProjectFileIORegistry.cpp
|
||||
|
||||
Paul Licameli
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "ProjectFileIORegistry.h"
|
||||
|
||||
#include "audacity/Types.h"
|
||||
#include <unordered_map>
|
||||
#include <wx/string.h>
|
||||
|
||||
|
||||
namespace ProjectFileIORegistry {
|
||||
|
||||
namespace {
|
||||
using TagTable = std::unordered_map< wxString, TagHandlerFactory >;
|
||||
static TagTable &sTagTable()
|
||||
{
|
||||
static TagTable theTable;
|
||||
return theTable;
|
||||
}
|
||||
}
|
||||
|
||||
Entry::Entry(
|
||||
const wxString &tag, const TagHandlerFactory &factory )
|
||||
{
|
||||
sTagTable()[ tag ] = factory;
|
||||
}
|
||||
|
||||
TagHandlerFactory Lookup( const wxString &tag )
|
||||
{
|
||||
const auto &table = sTagTable();
|
||||
auto iter = table.find( tag );
|
||||
if ( iter == table.end() )
|
||||
return {};
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
}
|
35
src/ProjectFileIORegistry.h
Normal file
35
src/ProjectFileIORegistry.h
Normal file
@ -0,0 +1,35 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
ProjectFileIORegistry.h
|
||||
|
||||
Paul Licameli
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_PROJECT_FILE_IO_REGISTRY__
|
||||
#define __AUDACITY_PROJECT_FILE_IO_REGISTRY__
|
||||
|
||||
#include <functional>
|
||||
|
||||
class AudacityProject;
|
||||
class XMLTagHandler;
|
||||
class wxString;
|
||||
|
||||
namespace ProjectFileIORegistry {
|
||||
|
||||
// Type of functions returning objects that intepret a part of the saved XML
|
||||
using TagHandlerFactory =
|
||||
std::function< XMLTagHandler *( AudacityProject & ) >;
|
||||
|
||||
// Typically statically constructed
|
||||
struct Entry{
|
||||
Entry( const wxString &tag, const TagHandlerFactory &factory );
|
||||
};
|
||||
|
||||
TagHandlerFactory Lookup( const wxString &tag );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -45,6 +45,8 @@
|
||||
|
||||
#include "FileNames.h"
|
||||
#include "Prefs.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectFileIORegistry.h"
|
||||
#include "ShuttleGui.h"
|
||||
#include "TranslatableStringArray.h"
|
||||
#include "widgets/Grid.h"
|
||||
@ -224,6 +226,11 @@ static const wxChar *DefaultGenres[] =
|
||||
wxT("Synthpop")
|
||||
};
|
||||
|
||||
static ProjectFileIORegistry::Entry registerFactory{
|
||||
wxT( "tags" ),
|
||||
[]( AudacityProject &project ){ return project.GetTags(); }
|
||||
};
|
||||
|
||||
Tags::Tags()
|
||||
{
|
||||
mEditTitle = true;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "Envelope.h"
|
||||
#include "Prefs.h"
|
||||
#include "Project.h"
|
||||
#include "ProjectFileIORegistry.h"
|
||||
#include "TrackArtist.h"
|
||||
#include "AllThemeResources.h"
|
||||
|
||||
@ -39,6 +40,15 @@ std::shared_ptr<TimeTrack> TrackFactory::NewTimeTrack()
|
||||
return std::make_shared<TimeTrack>(mDirManager, mZoomInfo);
|
||||
}
|
||||
|
||||
static ProjectFileIORegistry::Entry registerFactory{
|
||||
wxT( "timetrack" ),
|
||||
[]( AudacityProject &project ){
|
||||
auto &trackFactory = *project.GetTrackFactory();
|
||||
auto &tracks = *project.GetTracks();
|
||||
return tracks.Add(trackFactory.NewTimeTrack());
|
||||
}
|
||||
};
|
||||
|
||||
TimeTrack::TimeTrack(const std::shared_ptr<DirManager> &projDirManager, const ZoomInfo *zoomInfo):
|
||||
Track(projDirManager)
|
||||
, mZoomInfo(zoomInfo)
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "DirManager.h"
|
||||
#include "ShuttleGui.h"
|
||||
#include "Menus.h"
|
||||
#include "MissingAliasFileDialog.h"
|
||||
#include "Project.h"
|
||||
#include "Prefs.h"
|
||||
#include "widgets/NumericTextCtrl.h"
|
||||
@ -627,7 +628,11 @@ int TimerRecordDialog::ExecutePostRecordActions(bool bWasStopped) {
|
||||
|
||||
// Do Automatic Export?
|
||||
if (m_bAutoExportEnabled) {
|
||||
bExportOK = pProject->ExportFromTimerRecording(m_fnAutoExportFile, m_iAutoExportFormat,
|
||||
Exporter e;
|
||||
MissingAliasFilesDialog::SetShouldShow(true);
|
||||
bExportOK = e.ProcessFromTimerRecording(
|
||||
pProject, false, 0.0, pProject->GetTracks()->GetEndTime(),
|
||||
m_fnAutoExportFile, m_iAutoExportFormat,
|
||||
m_iAutoExportSubFormat, m_iAutoExportFilterIndex);
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ audio tracks.
|
||||
#include "LabelTrack.h"
|
||||
#include "TimeTrack.h"
|
||||
#include "Prefs.h"
|
||||
#include "prefs/GUIPrefs.h"
|
||||
#include "prefs/GUISettings.h"
|
||||
#include "prefs/SpectrogramSettings.h"
|
||||
#include "prefs/TracksPrefs.h"
|
||||
@ -142,7 +143,6 @@ TrackArtist::TrackArtist( TrackPanel *parent_ )
|
||||
mdBrange = ENV_DB_RANGE;
|
||||
mShowClipping = false;
|
||||
mSampleDisplay = 1;// Stem plots by default.
|
||||
UpdatePrefs();
|
||||
|
||||
SetColours(0);
|
||||
vruler = std::make_unique<Ruler>();
|
||||
@ -3267,15 +3267,22 @@ void TrackArt::DrawTimeTrack(TrackPanelDrawingContext &context,
|
||||
track->GetDisplayLog(), dbRange, lower, upper, false );
|
||||
}
|
||||
|
||||
void TrackArtist::UpdateSelectedPrefs( int id )
|
||||
{
|
||||
if( id == ShowClippingPrefsID())
|
||||
mShowClipping = gPrefs->Read(wxT("/GUI/ShowClipping"), mShowClipping);
|
||||
}
|
||||
|
||||
void TrackArtist::UpdatePrefs()
|
||||
{
|
||||
mdBrange = gPrefs->Read(ENV_DB_KEY, mdBrange);
|
||||
mShowClipping = gPrefs->Read(wxT("/GUI/ShowClipping"), mShowClipping);
|
||||
mSampleDisplay = TracksPrefs::SampleViewChoice();
|
||||
|
||||
mbShowTrackNameInTrack =
|
||||
gPrefs->ReadBool(wxT("/GUI/ShowTrackNameInWaveform"), false);
|
||||
|
||||
UpdateSelectedPrefs( ShowClippingPrefsID() );
|
||||
|
||||
SetColours(0);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <wx/brush.h> // member variable
|
||||
#include <wx/pen.h> // member variables
|
||||
#include "audacity/Types.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
class wxRect;
|
||||
|
||||
@ -157,7 +158,7 @@ namespace TrackArt {
|
||||
const wxRect & rect, int x0, int y0, int cy, bool top);
|
||||
}
|
||||
|
||||
class AUDACITY_DLL_API TrackArtist {
|
||||
class AUDACITY_DLL_API TrackArtist final : private PrefsListener {
|
||||
|
||||
public:
|
||||
TrackArtist( TrackPanel *parent_ );
|
||||
@ -174,7 +175,8 @@ public:
|
||||
|
||||
void SetColours(int iColorIndex);
|
||||
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
void UpdateSelectedPrefs( int id ) override;
|
||||
|
||||
void UpdateVRuler(const Track *t, const wxRect & rect);
|
||||
|
||||
|
@ -88,6 +88,9 @@ is time to refresh some aspect of the screen.
|
||||
#include "NoteTrack.h"
|
||||
#endif
|
||||
|
||||
#include "ondemand/ODManager.h"
|
||||
#include "ondemand/ODTask.h"
|
||||
|
||||
#include "toolbars/ControlToolBar.h"
|
||||
#include "toolbars/ToolsToolBar.h"
|
||||
|
||||
@ -180,6 +183,9 @@ BEGIN_EVENT_TABLE(TrackPanel, CellularPanel)
|
||||
EVT_PAINT(TrackPanel::OnPaint)
|
||||
|
||||
EVT_TIMER(wxID_ANY, TrackPanel::OnTimer)
|
||||
|
||||
EVT_COMMAND(wxID_ANY, EVT_ODTASK_UPDATE, TrackPanel::OnODTask)
|
||||
EVT_COMMAND(wxID_ANY, EVT_ODTASK_COMPLETE, TrackPanel::OnODTask)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
/// Makes a cursor from an XPM, uses CursorId as a fallback.
|
||||
@ -267,6 +273,8 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
|
||||
wxTheApp->Bind(EVT_AUDIOIO_PLAYBACK,
|
||||
&TrackPanel::OnPlayback,
|
||||
this);
|
||||
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
|
||||
@ -313,16 +321,8 @@ wxString TrackPanel::gSoloPref;
|
||||
|
||||
void TrackPanel::UpdatePrefs()
|
||||
{
|
||||
gPrefs->Read(wxT("/GUI/AutoScroll"), &mViewInfo->bUpdateTrackIndicator,
|
||||
true);
|
||||
gPrefs->Read(wxT("/GUI/Solo"), &gSoloPref, wxT("Simple"));
|
||||
|
||||
mViewInfo->UpdatePrefs();
|
||||
|
||||
if (mTrackArtist) {
|
||||
mTrackArtist->UpdatePrefs();
|
||||
}
|
||||
|
||||
// All vertical rulers must be recalculated since the minimum and maximum
|
||||
// frequences may have been changed.
|
||||
UpdateVRulers();
|
||||
@ -473,6 +473,14 @@ void TrackPanel::OnTimer(wxTimerEvent& )
|
||||
mTimeCount = 0;
|
||||
}
|
||||
|
||||
///Handles the redrawing necessary for tasks as they partially update in the
|
||||
///background, or finish.
|
||||
void TrackPanel::OnODTask(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
//todo: add track data to the event - check to see if the project contains it before redrawing.
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
double TrackPanel::GetScreenEndTime() const
|
||||
{
|
||||
int width;
|
||||
@ -2772,40 +2780,6 @@ void TrackInfo::UpdatePrefs( wxWindow *pParent )
|
||||
} while (textWidth >= allowableWidth);
|
||||
}
|
||||
|
||||
static TrackPanel * TrackPanelFactory(wxWindow * parent,
|
||||
wxWindowID id,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size,
|
||||
const std::shared_ptr<TrackList> &tracks,
|
||||
ViewInfo * viewInfo,
|
||||
TrackPanelListener * listener,
|
||||
AdornedRulerPanel * ruler)
|
||||
{
|
||||
wxASSERT(parent); // to justify safenew
|
||||
return safenew TrackPanel(
|
||||
parent,
|
||||
id,
|
||||
pos,
|
||||
size,
|
||||
tracks,
|
||||
viewInfo,
|
||||
listener,
|
||||
ruler);
|
||||
}
|
||||
|
||||
|
||||
// Declare the static factory function.
|
||||
// We defined it in the class.
|
||||
TrackPanel *(*TrackPanel::FactoryFunction)(
|
||||
wxWindow * parent,
|
||||
wxWindowID id,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size,
|
||||
const std::shared_ptr<TrackList> &tracks,
|
||||
ViewInfo * viewInfo,
|
||||
TrackPanelListener * listener,
|
||||
AdornedRulerPanel * ruler) = TrackPanelFactory;
|
||||
|
||||
TrackPanelNode::TrackPanelNode()
|
||||
{
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <wx/timer.h> // to inherit
|
||||
|
||||
#include "HitTestResult.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
#include "SelectedRegion.h"
|
||||
|
||||
@ -210,6 +211,8 @@ namespace TrackInfo
|
||||
wxWindow *pParent);
|
||||
#endif
|
||||
|
||||
// Non-member, namespace function relying on TrackPanel to invoke it
|
||||
// when it handles preference update events
|
||||
void UpdatePrefs( wxWindow *pParent );
|
||||
};
|
||||
|
||||
@ -251,6 +254,7 @@ enum : int {
|
||||
class AUDACITY_DLL_API TrackPanel final
|
||||
: public CellularPanel
|
||||
, public NonKeystrokeInterceptingWindow
|
||||
, private PrefsListener
|
||||
{
|
||||
public:
|
||||
TrackPanel(wxWindow * parent,
|
||||
@ -264,7 +268,7 @@ class AUDACITY_DLL_API TrackPanel final
|
||||
|
||||
virtual ~ TrackPanel();
|
||||
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
void ApplyUpdatedTheme();
|
||||
|
||||
void OnPaint(wxPaintEvent & event);
|
||||
@ -280,6 +284,7 @@ class AUDACITY_DLL_API TrackPanel final
|
||||
|
||||
void OnIdle(wxIdleEvent & event);
|
||||
void OnTimer(wxTimerEvent& event);
|
||||
void OnODTask(wxCommandEvent &event);
|
||||
|
||||
int GetLeftOffset() const { return GetLabelWidth() + 1;}
|
||||
|
||||
@ -370,16 +375,6 @@ public:
|
||||
ViewInfo * GetViewInfo(){ return mViewInfo;}
|
||||
TrackPanelListener * GetListener(){ return mListener;}
|
||||
AdornedRulerPanel * GetRuler(){ return mRuler;}
|
||||
// JKC and here is a factory function which just does 'NEW' in standard Audacity.
|
||||
// Precondition: parent != NULL
|
||||
static TrackPanel *(*FactoryFunction)(wxWindow * parent,
|
||||
wxWindowID id,
|
||||
const wxPoint & pos,
|
||||
const wxSize & size,
|
||||
const std::shared_ptr<TrackList> &tracks,
|
||||
ViewInfo * viewInfo,
|
||||
TrackPanelListener * listener,
|
||||
AdornedRulerPanel * ruler);
|
||||
|
||||
protected:
|
||||
void DrawTracks(wxDC * dc);
|
||||
|
@ -146,6 +146,14 @@ ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond)
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
void ViewInfo::UpdateSelectedPrefs( int id )
|
||||
{
|
||||
if (id == UpdateScrollPrefsID())
|
||||
gPrefs->Read(wxT("/GUI/AutoScroll"), &bUpdateTrackIndicator,
|
||||
true);
|
||||
ZoomInfo::UpdateSelectedPrefs( id );
|
||||
}
|
||||
|
||||
void ViewInfo::UpdatePrefs()
|
||||
{
|
||||
ZoomInfo::UpdatePrefs();
|
||||
@ -155,6 +163,8 @@ void ViewInfo::UpdatePrefs()
|
||||
#endif
|
||||
gPrefs->Read(wxT("/GUI/AdjustSelectionEdges"), &bAdjustSelectionEdges,
|
||||
true);
|
||||
|
||||
UpdateSelectedPrefs( UpdateScrollPrefsID() );
|
||||
}
|
||||
|
||||
void ViewInfo::SetBeforeScreenWidth(wxInt64 beforeWidth, wxInt64 screenWidth, double lowerBoundTime)
|
||||
@ -206,3 +216,9 @@ void ViewInfo::OnTimer(wxCommandEvent &event)
|
||||
// Propagate the message to other listeners bound to this
|
||||
this->ProcessEvent( event );
|
||||
}
|
||||
|
||||
int ViewInfo::UpdateScrollPrefsID()
|
||||
{
|
||||
static int value = wxNewId();
|
||||
return value;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <wx/event.h> // inherit wxEvtHandler
|
||||
#include "SelectedRegion.h"
|
||||
#include "MemoryX.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
|
||||
class Track;
|
||||
@ -31,6 +32,7 @@ class Track;
|
||||
class AUDACITY_DLL_API ZoomInfo /* not final */
|
||||
// Note that ViewInfo inherits from ZoomInfo but there are no virtual functions.
|
||||
// That's okay if we pass always by reference and never copy, suffering "slicing."
|
||||
: protected PrefsListener
|
||||
{
|
||||
public:
|
||||
ZoomInfo(double start, double pixelsPerSecond);
|
||||
@ -40,7 +42,7 @@ public:
|
||||
ZoomInfo(const ZoomInfo&) PROHIBITED;
|
||||
ZoomInfo& operator= (const ZoomInfo&) PROHIBITED;
|
||||
|
||||
void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
|
||||
int vpos; // vertical scroll pos
|
||||
|
||||
@ -146,7 +148,9 @@ class AUDACITY_DLL_API ViewInfo final
|
||||
public:
|
||||
ViewInfo(double start, double screenDuration, double pixelsPerSecond);
|
||||
|
||||
void UpdatePrefs();
|
||||
static int UpdateScrollPrefsID();
|
||||
void UpdatePrefs() override;
|
||||
void UpdateSelectedPrefs( int id ) override;
|
||||
|
||||
double GetBeforeScreenWidth() const
|
||||
{
|
||||
|
@ -48,6 +48,7 @@ Track classes.
|
||||
#include "Spectrum.h"
|
||||
|
||||
#include "Project.h"
|
||||
#include "ProjectFileIORegistry.h"
|
||||
|
||||
#include "AudioIO.h"
|
||||
#include "Prefs.h"
|
||||
@ -69,6 +70,15 @@ Track classes.
|
||||
|
||||
using std::max;
|
||||
|
||||
static ProjectFileIORegistry::Entry registerFactory{
|
||||
wxT( "wavetrack" ),
|
||||
[]( AudacityProject &project ){
|
||||
auto &trackFactory = *project.GetTrackFactory();
|
||||
auto &tracks = *project.GetTracks();
|
||||
return tracks.Add(trackFactory.NewWaveTrack());
|
||||
}
|
||||
};
|
||||
|
||||
WaveTrack::Holder TrackFactory::DuplicateWaveTrack(const WaveTrack &orig)
|
||||
{
|
||||
return std::static_pointer_cast<WaveTrack>( orig.Duplicate() );
|
||||
|
@ -3529,9 +3529,10 @@ void EffectUIHost::OnPlay(wxCommandEvent & WXUNUSED(evt))
|
||||
mPlayPos = mRegion.t1();
|
||||
}
|
||||
|
||||
mProject->GetControlToolBar()->PlayPlayRegion
|
||||
(SelectedRegion(mPlayPos, mRegion.t1()),
|
||||
mProject->GetDefaultPlayOptions(), PlayMode::normalPlay);
|
||||
mProject->GetControlToolBar()->PlayPlayRegion(
|
||||
SelectedRegion(mPlayPos, mRegion.t1()),
|
||||
mProject->GetDefaultPlayOptions(),
|
||||
PlayMode::normalPlay );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../FileNames.h"
|
||||
#include "../LabelTrack.h"
|
||||
#include "../MissingAliasFileDialog.h"
|
||||
#include "../Menus.h"
|
||||
#include "../NoteTrack.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../Printing.h"
|
||||
@ -121,7 +122,7 @@ AudacityProject *DoImportMIDI(
|
||||
|
||||
if (::ImportMIDI(fileName, newTrack.get())) {
|
||||
|
||||
pProject->SelectNone();
|
||||
SelectActions::SelectNone( *pProject );
|
||||
auto pTrack = tracks->Add( newTrack );
|
||||
pTrack->SetSelected(true);
|
||||
|
||||
@ -467,7 +468,7 @@ void OnImportLabels(const CommandContext &context)
|
||||
|
||||
newTrack->Import(f);
|
||||
|
||||
project.SelectNone();
|
||||
SelectActions::SelectNone( project );
|
||||
newTrack->SetSelected(true);
|
||||
tracks->Add( newTrack );
|
||||
|
||||
|
@ -412,7 +412,7 @@ bool DoEffect(
|
||||
if (flags & kConfigured)
|
||||
{
|
||||
TransportActions::DoStop(project);
|
||||
project.SelectAllIfNone();
|
||||
SelectActions::SelectAllIfNone( project );
|
||||
}
|
||||
|
||||
MissingAliasFilesDialog::SetShouldShow(true);
|
||||
|
@ -484,6 +484,24 @@ namespace SelectActions {
|
||||
|
||||
// exported helper functions
|
||||
|
||||
void SelectNone( AudacityProject &project )
|
||||
{
|
||||
for (auto t : project.GetTracks()->Any())
|
||||
t->SetSelected(false);
|
||||
|
||||
project.GetTrackPanel()->Refresh(false);
|
||||
}
|
||||
|
||||
// Select the full time range, if no
|
||||
// time range is selected.
|
||||
void SelectAllIfNone( AudacityProject &project )
|
||||
{
|
||||
auto flags = GetMenuManager( project ).GetUpdateFlags( project );
|
||||
if(!(flags & TracksSelectedFlag) ||
|
||||
(project.GetViewInfo().selectedRegion.isPoint()))
|
||||
DoSelectAllAudio( project );
|
||||
}
|
||||
|
||||
void DoListSelection
|
||||
(AudacityProject &project, Track *t, bool shift, bool ctrl, bool modifyState)
|
||||
{
|
||||
@ -549,7 +567,7 @@ void OnSelectNone(const CommandContext &context)
|
||||
auto &selectedRegion = project.GetViewInfo().selectedRegion;
|
||||
|
||||
selectedRegion.collapseToT0();
|
||||
project.SelectNone();
|
||||
SelectNone( project );
|
||||
project.ModifyState(false);
|
||||
}
|
||||
|
||||
|
@ -440,6 +440,11 @@ long mixer_process(void *mixer, float **buffer, long n)
|
||||
|
||||
#endif // EXPERIMENTAL_SCOREALIGN
|
||||
|
||||
enum{
|
||||
kAudacitySortByTime = (1 << 1),
|
||||
kAudacitySortByName = (1 << 2),
|
||||
};
|
||||
|
||||
//sort based on flags. see Project.h for sort flags
|
||||
void DoSortTracks( AudacityProject &project, int flags )
|
||||
{
|
||||
@ -797,7 +802,7 @@ void OnNewWaveTrack(const CommandContext &context)
|
||||
auto rate = project.GetRate();
|
||||
|
||||
auto t = tracks->Add(trackFactory->NewWaveTrack(defaultFormat, rate));
|
||||
project.SelectNone();
|
||||
SelectActions::SelectNone( project );
|
||||
|
||||
t->SetSelected(true);
|
||||
|
||||
@ -816,7 +821,7 @@ void OnNewStereoTrack(const CommandContext &context)
|
||||
auto defaultFormat = project.GetDefaultFormat();
|
||||
auto rate = project.GetRate();
|
||||
|
||||
project.SelectNone();
|
||||
SelectActions::SelectNone( project );
|
||||
|
||||
auto left = tracks->Add(trackFactory->NewWaveTrack(defaultFormat, rate));
|
||||
left->SetSelected(true);
|
||||
@ -841,7 +846,7 @@ void OnNewLabelTrack(const CommandContext &context)
|
||||
|
||||
auto t = tracks->Add(trackFactory->NewLabelTrack());
|
||||
|
||||
project.SelectNone();
|
||||
SelectActions::SelectNone( project );
|
||||
|
||||
t->SetSelected(true);
|
||||
|
||||
@ -865,7 +870,7 @@ void OnNewTimeTrack(const CommandContext &context)
|
||||
|
||||
auto t = tracks->AddToHead(trackFactory->NewTimeTrack());
|
||||
|
||||
project.SelectNone();
|
||||
SelectActions::SelectNone( project );
|
||||
|
||||
t->SetSelected(true);
|
||||
|
||||
|
@ -193,6 +193,14 @@ namespace TransportActions {
|
||||
|
||||
// exported helper functions
|
||||
|
||||
// Stop playing or recording, if paused.
|
||||
void StopIfPaused( AudacityProject &project )
|
||||
{
|
||||
auto flags = GetMenuManager( project ).GetUpdateFlags( project );
|
||||
if( flags & PausedFlag )
|
||||
DoStop( project );
|
||||
}
|
||||
|
||||
bool DoPlayStopSelect
|
||||
(AudacityProject &project, bool click, bool shift)
|
||||
{
|
||||
@ -699,8 +707,8 @@ void OnPlayOneSecond(const CommandContext &context)
|
||||
auto options = project.GetDefaultPlayOptions();
|
||||
|
||||
double pos = trackPanel->GetMostRecentXPos();
|
||||
controlToolBar->PlayPlayRegion
|
||||
(SelectedRegion(pos - 0.5, pos + 0.5), options,
|
||||
controlToolBar->PlayPlayRegion(
|
||||
SelectedRegion(pos - 0.5, pos + 0.5), options,
|
||||
PlayMode::oneSecondPlay);
|
||||
}
|
||||
|
||||
@ -751,8 +759,8 @@ void OnPlayToSelection(const CommandContext &context)
|
||||
auto controlToolBar = project.GetControlToolBar();
|
||||
auto playOptions = project.GetDefaultPlayOptions();
|
||||
|
||||
controlToolBar->PlayPlayRegion
|
||||
(SelectedRegion(t0, t1), playOptions, PlayMode::oneSecondPlay);
|
||||
controlToolBar->PlayPlayRegion(
|
||||
SelectedRegion(t0, t1), playOptions, PlayMode::oneSecondPlay);
|
||||
}
|
||||
|
||||
// The next 4 functions provide a limited version of the
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "../TrackPanel.h"
|
||||
#include "../commands/CommandContext.h"
|
||||
#include "../commands/CommandManager.h"
|
||||
#include "../prefs/GUIPrefs.h"
|
||||
#include "../prefs/TracksPrefs.h"
|
||||
|
||||
#ifdef EXPERIMENTAL_EFFECTS_RACK
|
||||
@ -367,7 +368,10 @@ void OnShowClipping(const CommandContext &context)
|
||||
gPrefs->Write(wxT("/GUI/ShowClipping"), checked);
|
||||
gPrefs->Flush();
|
||||
commandManager->Check(wxT("ShowClipping"), checked);
|
||||
trackPanel->UpdatePrefs();
|
||||
|
||||
wxTheApp->AddPendingEvent(wxCommandEvent{
|
||||
EVT_PREFS_UPDATE, ShowClippingPrefsID() });
|
||||
|
||||
trackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,10 @@ bool GUIPrefs::Commit()
|
||||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
// Reads preference /GUI/Theme
|
||||
theTheme.LoadPreferredTheme();
|
||||
ThemePrefs::ApplyUpdatedImages();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -366,6 +370,12 @@ wxString GUIPrefs::GetLang()
|
||||
return {};
|
||||
}
|
||||
|
||||
int ShowClippingPrefsID()
|
||||
{
|
||||
static int value = wxNewId();
|
||||
return value;
|
||||
}
|
||||
|
||||
PrefsPanel::Factory
|
||||
GUIPrefsFactory = [](wxWindow *parent, wxWindowID winid)
|
||||
{
|
||||
|
@ -67,4 +67,7 @@ class GUIPrefs final : public PrefsPanel
|
||||
|
||||
/// A PrefsPanel::Factory that creates one GUIPrefs panel.
|
||||
extern PrefsPanel::Factory GUIPrefsFactory;
|
||||
|
||||
int ShowClippingPrefsID();
|
||||
|
||||
#endif
|
||||
|
@ -68,7 +68,6 @@
|
||||
#include "MidiIOPrefs.h"
|
||||
#endif
|
||||
|
||||
#include "../Theme.h"
|
||||
#include "../widgets/HelpSystem.h"
|
||||
|
||||
#if wxUSE_ACCESSIBILITY
|
||||
@ -813,10 +812,6 @@ void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event))
|
||||
}
|
||||
gPrefs->Flush();
|
||||
|
||||
// Reads preference /GUI/Theme
|
||||
theTheme.LoadPreferredTheme();
|
||||
ThemePrefs::ApplyUpdatedImages();
|
||||
|
||||
SavePreferredPage();
|
||||
|
||||
#if USE_PORTMIXER
|
||||
@ -844,12 +839,14 @@ void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event))
|
||||
}
|
||||
#endif
|
||||
|
||||
// PRL: Is the following concern still valid, now that prefs update is
|
||||
// handled instead by delayed event processing?
|
||||
|
||||
// LL: wxMac can't handle recreating the menus when this dialog is still active,
|
||||
// so AudacityProject::UpdatePrefs() or any of the routines it calls must
|
||||
// not cause MenuCreator::RebuildMenuBar() to be executed.
|
||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
||||
gAudacityProjects[i]->UpdatePrefs();
|
||||
}
|
||||
|
||||
wxTheApp->AddPendingEvent(wxCommandEvent{ EVT_PREFS_UPDATE });
|
||||
|
||||
WaveformSettings::defaults().LoadPrefs();
|
||||
SpectrogramSettings::defaults().LoadPrefs();
|
||||
|
@ -127,6 +127,7 @@ ControlToolBar::~ControlToolBar()
|
||||
void ControlToolBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
// This is a convenience function that allows for button creation in
|
||||
@ -537,7 +538,6 @@ bool ControlToolBar::IsRecordDown() const
|
||||
int ControlToolBar::PlayPlayRegion(const SelectedRegion &selectedRegion,
|
||||
const AudioIOStartStreamOptions &options,
|
||||
PlayMode mode,
|
||||
PlayAppearance appearance, /* = PlayOption::Straight */
|
||||
bool backwards, /* = false */
|
||||
bool playWhiteSpace /* = false */)
|
||||
// STRONG-GUARANTEE (for state of mCutPreviewTracks)
|
||||
@ -563,7 +563,18 @@ int ControlToolBar::PlayPlayRegion(const SelectedRegion &selectedRegion,
|
||||
if (backwards)
|
||||
std::swap(t0, t1);
|
||||
|
||||
{
|
||||
PlayAppearance appearance;
|
||||
switch( mode ) {
|
||||
case PlayMode::cutPreviewPlay:
|
||||
appearance = PlayAppearance::CutPreview; break;
|
||||
case PlayMode::loopedPlay:
|
||||
appearance = PlayAppearance::Looped; break;
|
||||
default:
|
||||
appearance = PlayAppearance::Straight; break;
|
||||
}
|
||||
SetPlay(true, appearance);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
auto cleanup = finally( [&] {
|
||||
@ -577,7 +588,7 @@ int ControlToolBar::PlayPlayRegion(const SelectedRegion &selectedRegion,
|
||||
if (gAudioIO->IsBusy())
|
||||
return -1;
|
||||
|
||||
const bool cutpreview = appearance == PlayAppearance::CutPreview;
|
||||
const bool cutpreview = mode == PlayMode::cutPreviewPlay;
|
||||
if (cutpreview && t0==t1)
|
||||
return -1; /* msmeyer: makes no sense */
|
||||
|
||||
@ -589,7 +600,7 @@ int ControlToolBar::PlayPlayRegion(const SelectedRegion &selectedRegion,
|
||||
if (!t)
|
||||
return -1; // Should never happen, but...
|
||||
|
||||
p->mLastPlayMode = mode;
|
||||
mLastPlayMode = mode;
|
||||
|
||||
bool hasaudio;
|
||||
if (useMidi)
|
||||
@ -744,14 +755,13 @@ void ControlToolBar::PlayCurrentRegion(bool looped /* = false */,
|
||||
options.playLooped = looped;
|
||||
if (cutpreview)
|
||||
options.timeTrack = NULL;
|
||||
ControlToolBar::PlayAppearance appearance =
|
||||
cutpreview ? ControlToolBar::PlayAppearance::CutPreview
|
||||
: looped ? ControlToolBar::PlayAppearance::Looped
|
||||
: ControlToolBar::PlayAppearance::Straight;
|
||||
auto mode =
|
||||
cutpreview ? PlayMode::cutPreviewPlay
|
||||
: options.playLooped ? PlayMode::loopedPlay
|
||||
: PlayMode::normalPlay;
|
||||
PlayPlayRegion(SelectedRegion(playRegionStart, playRegionEnd),
|
||||
options,
|
||||
(looped ? PlayMode::loopedPlay : PlayMode::normalPlay),
|
||||
appearance);
|
||||
mode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1305,7 +1315,7 @@ void ControlToolBar::OnRewind(wxCommandEvent & WXUNUSED(evt))
|
||||
|
||||
AudacityProject *p = GetActiveProject();
|
||||
if (p) {
|
||||
p->StopIfPaused();
|
||||
TransportActions::StopIfPaused( *p );
|
||||
p->Rewind(mRewind->WasShiftDown());
|
||||
}
|
||||
}
|
||||
@ -1318,7 +1328,7 @@ void ControlToolBar::OnFF(wxCommandEvent & WXUNUSED(evt))
|
||||
AudacityProject *p = GetActiveProject();
|
||||
|
||||
if (p) {
|
||||
p->StopIfPaused();
|
||||
TransportActions::StopIfPaused( *p );
|
||||
p->SkipEnd(mFF->WasShiftDown());
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,12 @@ class TimeTrack;
|
||||
struct AudioIOStartStreamOptions;
|
||||
class SelectedRegion;
|
||||
|
||||
// Defined in Project.h
|
||||
enum class PlayMode : int;
|
||||
enum class PlayMode : int {
|
||||
normalPlay,
|
||||
oneSecondPlay, // Disables auto-scrolling
|
||||
loopedPlay, // Disables auto-scrolling
|
||||
cutPreviewPlay
|
||||
};
|
||||
|
||||
class WaveTrack;
|
||||
using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
|
||||
@ -100,7 +104,6 @@ class ControlToolBar final : public ToolBar {
|
||||
int PlayPlayRegion(const SelectedRegion &selectedRegion,
|
||||
const AudioIOStartStreamOptions &options,
|
||||
PlayMode playMode,
|
||||
PlayAppearance appearance = PlayAppearance::Straight,
|
||||
bool backwards = false,
|
||||
// Allow t0 and t1 to be beyond end of tracks
|
||||
bool playWhiteSpace = false);
|
||||
@ -133,6 +136,8 @@ class ControlToolBar final : public ToolBar {
|
||||
// Cancel the addition of temporary recording tracks into the project
|
||||
void CancelRecording();
|
||||
|
||||
PlayMode GetLastPlayMode() const { return mLastPlayMode; }
|
||||
|
||||
private:
|
||||
|
||||
static AButton *MakeButton(
|
||||
@ -192,6 +197,8 @@ class ControlToolBar final : public ToolBar {
|
||||
wxString mStateRecord;
|
||||
wxString mStatePause;
|
||||
|
||||
PlayMode mLastPlayMode{ PlayMode::normalPlay };
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLASS(ControlToolBar)
|
||||
|
@ -64,6 +64,12 @@ BEGIN_EVENT_TABLE(DeviceToolBar, ToolBar)
|
||||
EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, DeviceToolBar::OnCaptureKey)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
static int DeviceToolbarPrefsID()
|
||||
{
|
||||
static int value = wxNewId();
|
||||
return value;
|
||||
}
|
||||
|
||||
//Standard contructor
|
||||
DeviceToolBar::DeviceToolBar()
|
||||
: ToolBar(DeviceBarID, _("Device"), wxT("Device"), true)
|
||||
@ -313,6 +319,13 @@ void DeviceToolBar::UpdatePrefs()
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void DeviceToolBar::UpdateSelectedPrefs( int id )
|
||||
{
|
||||
if (id == DeviceToolbarPrefsID())
|
||||
UpdatePrefs();
|
||||
ToolBar::UpdateSelectedPrefs( id );
|
||||
}
|
||||
|
||||
|
||||
void DeviceToolBar::EnableDisableButtons()
|
||||
{
|
||||
@ -773,10 +786,8 @@ void DeviceToolBar::OnChoice(wxCommandEvent &event)
|
||||
gAudioIO->HandleDeviceChange();
|
||||
}
|
||||
|
||||
// Update all projects' DeviceToolBar.
|
||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
||||
gAudacityProjects[i]->GetDeviceToolBar()->UpdatePrefs();
|
||||
}
|
||||
wxTheApp->AddPendingEvent(wxCommandEvent{
|
||||
EVT_PREFS_UPDATE, DeviceToolbarPrefsID() });
|
||||
}
|
||||
|
||||
void DeviceToolBar::ShowInputDialog()
|
||||
|
@ -29,6 +29,7 @@ class DeviceToolBar final : public ToolBar {
|
||||
void Create(wxWindow * parent) override;
|
||||
|
||||
void UpdatePrefs() override;
|
||||
void UpdateSelectedPrefs( int ) override;
|
||||
|
||||
void DeinitChildren();
|
||||
void Populate() override;
|
||||
|
@ -89,6 +89,7 @@ EditToolBar::~EditToolBar()
|
||||
void EditToolBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
void EditToolBar::AddSeparator()
|
||||
|
@ -78,6 +78,8 @@ void MeterToolBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
|
||||
UpdatePrefs();
|
||||
|
||||
// Simulate a size event to set initial meter placement/size
|
||||
wxSizeEvent dummy;
|
||||
OnSize(dummy);
|
||||
@ -156,18 +158,6 @@ void MeterToolBar::Populate()
|
||||
|
||||
void MeterToolBar::UpdatePrefs()
|
||||
{
|
||||
if( mPlayMeter )
|
||||
{
|
||||
mPlayMeter->UpdatePrefs();
|
||||
mPlayMeter->Refresh();
|
||||
}
|
||||
|
||||
if( mRecordMeter )
|
||||
{
|
||||
mRecordMeter->UpdatePrefs();
|
||||
mRecordMeter->Refresh();
|
||||
}
|
||||
|
||||
RegenerateTooltips();
|
||||
|
||||
// Set label to pull in language change
|
||||
@ -175,8 +165,6 @@ void MeterToolBar::UpdatePrefs()
|
||||
|
||||
// Give base class a chance
|
||||
ToolBar::UpdatePrefs();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MeterToolBar::RegenerateTooltips()
|
||||
|
@ -67,6 +67,7 @@ MixerToolBar::~MixerToolBar()
|
||||
void MixerToolBar::Create(wxWindow *parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
void MixerToolBar::Populate()
|
||||
|
@ -68,6 +68,7 @@ ScrubbingToolBar::~ScrubbingToolBar()
|
||||
void ScrubbingToolBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
/// This is a convenience function that allows for button creation in
|
||||
|
@ -132,6 +132,7 @@ SelectionBar::~SelectionBar()
|
||||
void SelectionBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
|
||||
@ -504,6 +505,7 @@ void SelectionBar::OnUpdate(wxCommandEvent &evt)
|
||||
// Save format name before recreating the controls so they resize properly
|
||||
{
|
||||
auto format = mStartTime->GetBuiltinName(index);
|
||||
if (mListener)
|
||||
mListener->AS_SetSelectionFormat(format);
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,7 @@ SpectralSelectionBar::~SpectralSelectionBar()
|
||||
void SpectralSelectionBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
mHeight = wxWindowBase::GetSizer()->GetSize().GetHeight();
|
||||
}
|
||||
|
||||
@ -370,11 +371,13 @@ void SpectralSelectionBar::OnUpdate(wxCommandEvent &evt)
|
||||
if (type == EVT_FREQUENCYTEXTCTRL_UPDATED) {
|
||||
NumericTextCtrl *frequencyCtrl = (mbCenterAndWidth ? mCenterCtrl : mLowCtrl);
|
||||
auto frequencyFormatName = frequencyCtrl->GetBuiltinName(index);
|
||||
if (mListener)
|
||||
mListener->SSBL_SetFrequencySelectionFormatName(frequencyFormatName);
|
||||
}
|
||||
else if (mbCenterAndWidth &&
|
||||
type == EVT_BANDWIDTHTEXTCTRL_UPDATED) {
|
||||
auto bandwidthFormatName = mWidthCtrl->GetBuiltinName(index);
|
||||
if (mListener)
|
||||
mListener->SSBL_SetBandwidthSelectionFormatName(bandwidthFormatName);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <vector>
|
||||
#include <wx/defs.h>
|
||||
|
||||
#include "../Prefs.h"
|
||||
#include "../Theme.h"
|
||||
#include "../widgets/wxPanelWrapper.h" // to inherit
|
||||
|
||||
@ -84,7 +85,9 @@ enum
|
||||
// How may pixels padding each side of a floating toolbar
|
||||
enum { ToolBarFloatMargin = 1 };
|
||||
|
||||
class ToolBar /* not final */ : public wxPanelWrapper
|
||||
class ToolBar /* not final */
|
||||
: public wxPanelWrapper
|
||||
, protected PrefsListener
|
||||
{
|
||||
|
||||
public:
|
||||
@ -101,7 +104,7 @@ class ToolBar /* not final */ : public wxPanelWrapper
|
||||
virtual void Create(wxWindow *parent);
|
||||
virtual void EnableDisableButtons() = 0;
|
||||
virtual void ReCreateButtons();
|
||||
virtual void UpdatePrefs();
|
||||
void UpdatePrefs() override;
|
||||
virtual void RegenerateTooltips() = 0;
|
||||
|
||||
int GetType();
|
||||
|
@ -1091,21 +1091,6 @@ void ToolManager::LayoutToolBars()
|
||||
mBotDock->LayoutToolBars();
|
||||
}
|
||||
|
||||
//
|
||||
// Tell the toolbars that preferences have been updated
|
||||
//
|
||||
void ToolManager::UpdatePrefs()
|
||||
{
|
||||
for( int ndx = 0; ndx < ToolBarCount; ndx++ )
|
||||
{
|
||||
ToolBar *bar = mBars[ ndx ].get();
|
||||
if( bar )
|
||||
{
|
||||
bar->UpdatePrefs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle toolbar dragging
|
||||
//
|
||||
|
@ -48,7 +48,6 @@ class ToolManager final : public wxEvtHandler, public wxEventFilter
|
||||
~ToolManager();
|
||||
|
||||
void LayoutToolBars();
|
||||
void UpdatePrefs();
|
||||
|
||||
bool IsDocked( int type );
|
||||
|
||||
|
@ -258,3 +258,9 @@ void ToolsToolBar::OnTool(wxCommandEvent & evt)
|
||||
IsDown(multiTool));
|
||||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
void ToolsToolBar::Create(wxWindow * parent)
|
||||
{
|
||||
ToolBar::Create(parent);
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ class ToolsToolBar final : public ToolBar {
|
||||
|
||||
private:
|
||||
|
||||
void Create(wxWindow * parent) override;
|
||||
void RegenerateTooltips() override;
|
||||
wxImage *MakeToolImage(wxImage *tool, wxImage *mask, int style);
|
||||
static AButton *MakeTool(
|
||||
|
@ -483,18 +483,15 @@ void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
|
||||
AudioIOStartStreamOptions options(p->GetDefaultPlayOptions());
|
||||
options.playLooped = looped;
|
||||
// No need to set cutPreview options.
|
||||
// Due to a rather hacky approach, the appearance is used
|
||||
// to signal use of cutpreview to code below.
|
||||
options.timeTrack = mTimeTrack.get();
|
||||
ControlToolBar::PlayAppearance appearance =
|
||||
cutPreview ? ControlToolBar::PlayAppearance::CutPreview
|
||||
: looped ? ControlToolBar::PlayAppearance::Looped
|
||||
: ControlToolBar::PlayAppearance::Straight;
|
||||
auto mode =
|
||||
cutPreview ? PlayMode::cutPreviewPlay
|
||||
: options.playLooped ? PlayMode::loopedPlay
|
||||
: PlayMode::normalPlay;
|
||||
p->GetControlToolBar()->PlayPlayRegion
|
||||
(SelectedRegion(playRegionStart, playRegionEnd),
|
||||
options,
|
||||
PlayMode::normalPlay,
|
||||
appearance);
|
||||
mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -98,7 +98,6 @@ class TranscriptionToolBar final : public ToolBar {
|
||||
//void Populate() override;
|
||||
//void Repaint(wxDC * WXUNUSED(dc)) override {}
|
||||
//void EnableDisableButtons() override;
|
||||
//void UpdatePrefs() override;
|
||||
|
||||
//void OnFocus(wxFocusEvent &event);
|
||||
//void OnCaptureKey(wxCommandEvent &event);
|
||||
|
@ -36,6 +36,11 @@ EditCursorOverlay::EditCursorOverlay(AudacityProject *project, bool isMaster)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned EditCursorOverlay::SequenceNumber() const
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool> EditCursorOverlay::DoGetRectangle(wxSize size)
|
||||
{
|
||||
const auto &selection = mProject->GetViewInfo().selectedRegion;
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
EditCursorOverlay(AudacityProject *project, bool isMaster = true);
|
||||
|
||||
private:
|
||||
unsigned SequenceNumber() const override;
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw(OverlayPanel &panel, wxDC &dc) override;
|
||||
|
||||
|
@ -17,6 +17,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../Project.h"
|
||||
#include "../../TrackPanel.h"
|
||||
#include "Scrubbing.h"
|
||||
#include "../../toolbars/ControlToolBar.h"
|
||||
|
||||
#include <wx/dc.h>
|
||||
|
||||
@ -42,6 +43,11 @@ PlayIndicatorOverlayBase::~PlayIndicatorOverlayBase()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned PlayIndicatorOverlayBase::SequenceNumber() const
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool> PlayIndicatorOverlayBase::DoGetRectangle(wxSize size)
|
||||
{
|
||||
auto width = mIsMaster ? 1 : IndicatorMediumWidth;
|
||||
@ -171,9 +177,10 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event)
|
||||
playPos >= 0 && !onScreen ) {
|
||||
// msmeyer: But only if not playing looped or in one-second mode
|
||||
// PRL: and not scrolling with play/record head fixed
|
||||
auto mode = mProject->GetControlToolBar()->GetLastPlayMode();
|
||||
if (!pinned &&
|
||||
mProject->mLastPlayMode != PlayMode::loopedPlay &&
|
||||
mProject->mLastPlayMode != PlayMode::oneSecondPlay &&
|
||||
mode != PlayMode::loopedPlay &&
|
||||
mode != PlayMode::oneSecondPlay &&
|
||||
!gAudioIO->IsPaused())
|
||||
{
|
||||
auto newPos = playPos;
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
void Update(int newIndicatorX) { mNewIndicatorX = newIndicatorX; }
|
||||
|
||||
private:
|
||||
unsigned SequenceNumber() const override;
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw(OverlayPanel &panel, wxDC &dc) override;
|
||||
|
||||
|
@ -394,13 +394,6 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
#endif
|
||||
std::max(0.0, MinStutter);
|
||||
|
||||
ControlToolBar::PlayAppearance appearance =
|
||||
// commented out to fix Bug 1241
|
||||
// mSeeking
|
||||
// ? ControlToolBar::PlayAppearance::Seek
|
||||
// : ControlToolBar::PlayAppearance::Scrub;
|
||||
ControlToolBar::PlayAppearance::Straight;
|
||||
// const bool cutPreview = false;
|
||||
const bool backwards = time1 < time0;
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
|
||||
static const double maxScrubSpeedBase =
|
||||
@ -421,7 +414,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
|
||||
mScrubToken =
|
||||
ctb->PlayPlayRegion(SelectedRegion(time0, time1), options,
|
||||
PlayMode::normalPlay, appearance, backwards);
|
||||
PlayMode::normalPlay, backwards);
|
||||
if (mScrubToken <= 0) {
|
||||
// Bug1627 (part of it):
|
||||
// infinite error spew when trying to start scrub:
|
||||
@ -485,8 +478,6 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1)
|
||||
mOptions.adjustStart = false;
|
||||
mOptions.isPlayingAtSpeed = true;
|
||||
|
||||
ControlToolBar::PlayAppearance appearance = ControlToolBar::PlayAppearance::Straight;
|
||||
|
||||
const bool backwards = time1 < time0;
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
|
||||
static const double maxScrubSpeedBase =
|
||||
@ -510,7 +501,7 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1)
|
||||
mScrubToken =
|
||||
// Reduce time by 'stopTolerance' fudge factor, so that the Play will stop.
|
||||
ctb->PlayPlayRegion(SelectedRegion(time0, time1-stopTolerance), options,
|
||||
PlayMode::normalPlay, appearance, backwards);
|
||||
PlayMode::normalPlay, backwards);
|
||||
|
||||
if (mScrubToken >= 0) {
|
||||
mLastScrubPosition = 0;
|
||||
@ -886,6 +877,11 @@ ScrubbingOverlay::ScrubbingOverlay(AudacityProject *project)
|
||||
this);
|
||||
}
|
||||
|
||||
unsigned ScrubbingOverlay::SequenceNumber() const
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
|
||||
std::pair<wxRect, bool> ScrubbingOverlay::DoGetRectangle(wxSize)
|
||||
{
|
||||
wxRect rect(mLastScrubRect);
|
||||
|
@ -216,6 +216,7 @@ public:
|
||||
ScrubbingOverlay(AudacityProject *project);
|
||||
|
||||
private:
|
||||
unsigned SequenceNumber() const override;
|
||||
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
|
||||
void Draw(OverlayPanel &panel, wxDC &dc) override;
|
||||
|
||||
|
@ -145,7 +145,7 @@ UIHandle::Result CloseButtonHandle::CommitChanges
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (pTrack)
|
||||
{
|
||||
pProject->StopIfPaused();
|
||||
TransportActions::StopIfPaused( *pProject );
|
||||
if (!pProject->IsAudioActive()) {
|
||||
// This pushes an undo item:
|
||||
TrackActions::DoRemoveTrack(*pProject, pTrack.get());
|
||||
|
@ -253,9 +253,6 @@ bool MeterUpdateQueue::Get(MeterUpdateMsg &msg)
|
||||
// How many pixels between items?
|
||||
const static int gap = 2;
|
||||
|
||||
// Event used to notify all meters of preference changes
|
||||
wxDEFINE_EVENT(EVT_METER_PREFERENCES_CHANGED, wxCommandEvent);
|
||||
|
||||
const static wxChar *PrefStyles[] =
|
||||
{
|
||||
wxT("AutomaticStereo"),
|
||||
@ -348,11 +345,6 @@ MeterPanel::MeterPanel(AudacityProject *project,
|
||||
mPeakPeakPen = wxPen(theTheme.Colour( clrMeterPeak), 1, wxPENSTYLE_SOLID);
|
||||
mDisabledPen = wxPen(theTheme.Colour( clrMeterDisabledPen), 1, wxPENSTYLE_SOLID);
|
||||
|
||||
// Register for our preference update event
|
||||
wxTheApp->Bind(EVT_METER_PREFERENCES_CHANGED,
|
||||
&MeterPanel::OnMeterPrefsUpdated,
|
||||
this);
|
||||
|
||||
if (mIsInput) {
|
||||
wxTheApp->Bind(EVT_AUDIOIO_MONITOR,
|
||||
&MeterPanel::OnAudioIOStatus,
|
||||
@ -457,6 +449,20 @@ void MeterPanel::UpdatePrefs()
|
||||
Reset(mRate, false);
|
||||
|
||||
mLayoutValid = false;
|
||||
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
static int MeterPrefsID()
|
||||
{
|
||||
static int value = wxNewId();
|
||||
return value;
|
||||
}
|
||||
|
||||
void MeterPanel::UpdateSelectedPrefs(int id)
|
||||
{
|
||||
if (id == MeterPrefsID())
|
||||
UpdatePrefs();
|
||||
}
|
||||
|
||||
void MeterPanel::OnErase(wxEraseEvent & WXUNUSED(event))
|
||||
@ -1964,15 +1970,6 @@ void MeterPanel::OnMonitor(wxCommandEvent & WXUNUSED(event))
|
||||
StartMonitoring();
|
||||
}
|
||||
|
||||
void MeterPanel::OnMeterPrefsUpdated(wxCommandEvent & evt)
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
UpdatePrefs();
|
||||
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
void MeterPanel::OnPreferences(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
wxTextCtrl *rate;
|
||||
@ -2099,9 +2096,8 @@ void MeterPanel::OnPreferences(wxCommandEvent & WXUNUSED(event))
|
||||
// Currently, there are 2 playback meters and 2 record meters and any number of
|
||||
// mixerboard meters, so we have to send out an preferences updated message to
|
||||
// ensure they all update themselves.
|
||||
wxCommandEvent e(EVT_METER_PREFERENCES_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
GetParent()->GetEventHandler()->ProcessEvent(e);
|
||||
wxTheApp->AddPendingEvent(wxCommandEvent{
|
||||
EVT_PREFS_UPDATE, MeterPrefsID() });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,14 +22,11 @@
|
||||
#include <wx/timer.h> // member variable
|
||||
|
||||
#include "../SampleFormat.h"
|
||||
#include "../Prefs.h"
|
||||
#include "Ruler.h" // member variable
|
||||
|
||||
class AudacityProject;
|
||||
|
||||
// Event used to notify all meters of preference changes
|
||||
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_METER_PREFERENCES_CHANGED, wxCommandEvent);
|
||||
|
||||
// Increase this when we add support for multichannel meters
|
||||
// (most of the code is already there)
|
||||
const int kMaxMeterBars = 2;
|
||||
@ -94,7 +91,7 @@ class MeterAx;
|
||||
\brief MeterPanel is a panel that paints the meter used for monitoring
|
||||
or playback.
|
||||
************************************************************************/
|
||||
class MeterPanel final : public wxPanelWrapper
|
||||
class MeterPanel final : public wxPanelWrapper, private PrefsListener
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(MeterPanel)
|
||||
|
||||
@ -124,7 +121,6 @@ class MeterPanel final : public wxPanelWrapper
|
||||
|
||||
void SetFocusFromKbd() override;
|
||||
|
||||
void UpdatePrefs();
|
||||
void Clear();
|
||||
|
||||
Style GetStyle() const { return mStyle; }
|
||||
@ -192,6 +188,9 @@ class MeterPanel final : public wxPanelWrapper
|
||||
int GetDBRange() const { return mDB ? mDBRange : -1; }
|
||||
|
||||
private:
|
||||
void UpdatePrefs() override;
|
||||
void UpdateSelectedPrefs( int ) override;
|
||||
|
||||
static bool s_AcceptsFocus;
|
||||
struct Resetter { void operator () (bool *p) const { if(p) *p = false; } };
|
||||
using TempAllowFocus = std::unique_ptr<bool, Resetter>;
|
||||
@ -232,7 +231,6 @@ class MeterPanel final : public wxPanelWrapper
|
||||
void ShowMenu(const wxPoint & pos);
|
||||
void OnMonitor(wxCommandEvent &evt);
|
||||
void OnPreferences(wxCommandEvent &evt);
|
||||
void OnMeterPrefsUpdated(wxCommandEvent &evt);
|
||||
|
||||
wxString Key(const wxString & key) const;
|
||||
|
||||
|
@ -93,6 +93,10 @@ class Overlay
|
||||
public:
|
||||
virtual ~Overlay() = 0;
|
||||
|
||||
///\brief This number determines an ordering of overlays, so that those
|
||||
/// with higher numbers overpaint those with lower numbers that intersect
|
||||
virtual unsigned SequenceNumber() const = 0;
|
||||
|
||||
// nonvirtual wrapper
|
||||
std::pair<wxRect, bool> GetRectangle(wxSize size);
|
||||
|
||||
|
@ -23,7 +23,16 @@ OverlayPanel::OverlayPanel(wxWindow * parent, wxWindowID id,
|
||||
|
||||
void OverlayPanel::AddOverlay( const std::weak_ptr<Overlay> &pOverlay)
|
||||
{
|
||||
mOverlays.push_back(pOverlay);
|
||||
if (pOverlay.expired())
|
||||
return;
|
||||
Compress();
|
||||
auto iter = std::lower_bound( mOverlays.begin(), mOverlays.end(),
|
||||
pOverlay.lock()->SequenceNumber(),
|
||||
[]( const OverlayPtr &p, unsigned value ) {
|
||||
return p.expired() || p.lock()->SequenceNumber() < value;
|
||||
}
|
||||
);
|
||||
mOverlays.insert(iter, pOverlay);
|
||||
}
|
||||
|
||||
void OverlayPanel::ClearOverlays()
|
||||
|
@ -40,8 +40,10 @@ public:
|
||||
void DrawOverlays(bool repaint_all, wxDC *pDC = nullptr);
|
||||
|
||||
private:
|
||||
using OverlayPtr = std::weak_ptr<Overlay>;
|
||||
|
||||
void Compress();
|
||||
std::vector< std::weak_ptr<Overlay> > mOverlays;
|
||||
std::vector< OverlayPtr > mOverlays;
|
||||
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
@ -221,6 +221,7 @@
|
||||
<ClCompile Include="..\..\..\src\Printing.cpp" />
|
||||
<ClCompile Include="..\..\..\src\Profiler.cpp" />
|
||||
<ClCompile Include="..\..\..\src\Project.cpp" />
|
||||
<ClCompile Include="..\..\..\src\ProjectFileIORegistry.cpp" />
|
||||
<ClCompile Include="..\..\..\src\ProjectFSCK.cpp" />
|
||||
<ClCompile Include="..\..\..\src\RealFFTf.cpp" />
|
||||
<ClCompile Include="..\..\..\src\RealFFTf48x.cpp" />
|
||||
@ -645,6 +646,7 @@
|
||||
<ClInclude Include="..\..\..\src\Printing.h" />
|
||||
<ClInclude Include="..\..\..\src\Profiler.h" />
|
||||
<ClInclude Include="..\..\..\src\Project.h" />
|
||||
<ClInclude Include="..\..\..\src\ProjectFileIORegistry.h" />
|
||||
<ClInclude Include="..\..\..\src\ProjectFSCK.h" />
|
||||
<ClInclude Include="..\..\..\src\RealFFTf.h" />
|
||||
<ClInclude Include="..\..\..\src\Resample.h" />
|
||||
|
@ -260,6 +260,9 @@
|
||||
<ClCompile Include="..\..\..\src\Project.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\ProjectFileIORegistry.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\ProjectFSCK.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
@ -1315,6 +1318,9 @@
|
||||
<ClInclude Include="..\..\..\src\Project.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\ProjectFileIORegistry.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\ProjectFSCK.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
x
Reference in New Issue
Block a user