static Tags::Get...

... not member functions of AudacityProject
This commit is contained in:
Paul Licameli 2019-01-22 16:32:14 -05:00
parent 116ff70756
commit c1c0030013
12 changed files with 72 additions and 53 deletions

View File

@ -1325,9 +1325,6 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
// MM: Give track panel the focus to ensure keyboard commands work
mTrackPanel->SetFocus();
// Create tags object
mTags = std::make_shared<Tags>();
InitialState();
FixScrollbars();
mRuler->SetLeftOffset(mTrackPanel->GetLeftOffset()); // bevel on AdornedRuler
@ -1513,21 +1510,6 @@ bool AudacityProject::IsAudioActive() const
gAudioIO->IsStreamActive(GetAudioIOToken());
}
Tags *AudacityProject::GetTags()
{
return mTags.get();
}
const Tags *AudacityProject::GetTags() const
{
return mTags.get();
}
void AudacityProject::SetTags( const std::shared_ptr<Tags> &tags )
{
mTags = tags;
}
wxString AudacityProject::GetProjectName() const
{
wxString name = wxFileNameFromPath(mFileName);
@ -2657,8 +2639,6 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
TrackFactory::Destroy( project );
mTags.reset();
// Delete all the tracks to free up memory and DirManager references.
tracks.Clear();
@ -3695,6 +3675,7 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCopy)
auto &tracks = TrackList::Get( proj );
auto &viewInfo = ViewInfo::Get( proj );
auto &dirManager = DirManager::Get( proj );
auto &tags = Tags::Get( proj );
//TIMER_START( "AudacityProject::WriteXML", xml_writer_timer );
// Warning: This block of code is duplicated in Save, for now...
@ -3739,7 +3720,7 @@ void AudacityProject::WriteXML(XMLWriter &xmlFile, bool bWantSaveCopy)
xmlFile.WriteAttr(wxT("bandwidthformat"),
GetBandwidthSelectionFormatName().Internal());
mTags->WriteXML(xmlFile);
tags.WriteXML(xmlFile);
unsigned int ndx = 0;
tracks.Any().Visit(
@ -4326,18 +4307,24 @@ bool AudacityProject::Import(const FilePath &fileName, WaveTrackArray* pTrackArr
{
auto &project = *this;
auto &dirManager = DirManager::Get( project );
auto oldTags = Tags::Get( project ).shared_from_this();
TrackHolders newTracks;
wxString errorMessage;
{
// Backup Tags, before the import. Be prepared to roll back changes.
auto cleanup = valueRestorer( mTags,
mTags ? mTags->Duplicate() : decltype(mTags){} );
bool committed = false;
auto cleanup = finally([&]{
if ( !committed )
Tags::Set( project, oldTags );
});
auto newTags = oldTags->Duplicate();
Tags::Set( project, newTags );
bool success = Importer::Get().Import(fileName,
&TrackFactory::Get( project ),
newTracks,
mTags.get(),
newTags.get(),
errorMessage);
if (!errorMessage.empty()) {
@ -4352,7 +4339,7 @@ bool AudacityProject::Import(const FilePath &fileName, WaveTrackArray* pTrackArr
FileHistory::Global().AddFileToHistory(fileName);
// no more errors, commit
cleanup.release();
committed = true;
}
// for LOF ("list of files") files, do not import the file as if it
@ -4627,11 +4614,12 @@ void AudacityProject::InitialState()
auto &tracks = TrackList::Get( project );
auto &viewInfo = ViewInfo::Get( project );
auto &undoManager = UndoManager::Get( project );
auto &tags = Tags::Get( project );
undoManager.ClearStates();
undoManager.PushState(
&tracks, viewInfo.selectedRegion, mTags,
&tracks, viewInfo.selectedRegion, tags.shared_from_this(),
_("Created new project"), wxT(""));
undoManager.StateSaved();
@ -4672,8 +4660,9 @@ void AudacityProject::PushState(const wxString &desc,
auto &tracks = TrackList::Get( project );
auto &viewInfo = ViewInfo::Get( project );
auto &undoManager = UndoManager::Get( project );
auto &tags = Tags::Get( project );
undoManager.PushState(
&tracks, viewInfo.selectedRegion, mTags,
&tracks, viewInfo.selectedRegion, tags.shared_from_this(),
desc, shortDesc, flags);
mDirty = true;
@ -4703,8 +4692,9 @@ void AudacityProject::ModifyState(bool bWantsAutoSave)
auto &tracks = TrackList::Get( project );
auto &viewInfo = ViewInfo::Get( project );
auto &undoManager = UndoManager::Get( project );
auto &tags = Tags::Get( project );
undoManager.ModifyState(
&tracks, viewInfo.selectedRegion, mTags);
&tracks, viewInfo.selectedRegion, tags.shared_from_this());
if (bWantsAutoSave)
AutoSave();
GetTrackPanel()->HandleCursorForPresentMouseState();
@ -4722,7 +4712,7 @@ void AudacityProject::PopState(const UndoState &state)
viewInfo.selectedRegion = state.selectedRegion;
// Restore tags
mTags = state.tags;
Tags::Set( project, state.tags );
TrackList *const tracks = state.tracks.get();

View File

@ -60,7 +60,6 @@ class Overlay;
class RecordingRecoveryHandler;
namespace ProjectFileIORegistry{ struct Entry; }
class TrackList;
class Tags;
class TrackPanel;
class FreqWindow;
@ -209,9 +208,6 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
wxString GetProjectName() const;
AdornedRulerPanel *GetRulerPanel();
Tags *GetTags();
const Tags *GetTags() const;
void SetTags( const std::shared_ptr<Tags> &tags );
int GetAudioIOToken() const;
bool IsAudioActive() const;
void SetAudioIOToken(int token);
@ -535,12 +531,6 @@ public:
double mRate;
sampleFormat mDefaultFormat;
// Tags (artist name, song properties, MP3 ID3 info, etc.)
// The structure may be shared with undo history entries
// To keep undo working correctly, always replace this with a NEW duplicate
// BEFORE doing any editing of it!
std::shared_ptr<Tags> mTags;
int mSnapTo;
NumericFormatSymbol mSelectionFormat;
NumericFormatSymbol mFrequencySelectionFormatName;

View File

@ -228,9 +228,30 @@ static const wxChar *DefaultGenres[] =
static ProjectFileIORegistry::Entry registerFactory{
wxT( "tags" ),
[]( AudacityProject &project ){ return project.GetTags(); }
[]( AudacityProject &project ){ return &Tags::Get( project ); }
};
static const AudacityProject::AttachedObjects::RegisteredFactory key{
[](AudacityProject &){ return std::make_shared< Tags >(); }
};
Tags &Tags::Get( AudacityProject &project )
{
return project.AttachedObjects::Get< Tags >( key );
}
const Tags &Tags::Get( const AudacityProject &project )
{
return Get( const_cast< AudacityProject & >( project ) );
}
Tags &Tags::Set( AudacityProject &project, const std::shared_ptr< Tags > &tags )
{
auto &result = *tags;
project.AttachedObjects::Assign( key, tags );
return result;
}
Tags::Tags()
{
mEditTitle = true;

View File

@ -33,10 +33,12 @@
#include "xml/XMLTagHandler.h"
#include "ClientData.h"
#include <utility>
#include "widgets/wxPanelWrapper.h" // to inherit
#include <memory>
#include <unordered_map>
#include "audacity/Types.h"
@ -47,6 +49,7 @@ class wxGridCellStringRenderer;
class wxGridEvent;
class wxTextCtrl;
class AudacityProject;
class Grid;
class ShuttleGui;
class TagsEditor;
@ -64,9 +67,20 @@ using TagMap = std::unordered_map< wxString, wxString >;
#define TAG_SOFTWARE wxT("Software")
#define TAG_COPYRIGHT wxT("Copyright")
class AUDACITY_DLL_API Tags final : public XMLTagHandler {
class AUDACITY_DLL_API Tags final
: public XMLTagHandler
, public std::enable_shared_from_this< Tags >
, public ClientData::Base
{
public:
static Tags &Get( AudacityProject &project );
static const Tags &Get( const AudacityProject &project );
// Returns reference to *tags
static Tags &Set(
AudacityProject &project, const std::shared_ptr<Tags> &tags );
Tags(); // constructor
Tags( const Tags& ) = default;
//Tags( Tags && ) = default;

View File

@ -340,7 +340,7 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const T
return false;
if (metadata == NULL)
metadata = project->GetTags();
metadata = &Tags::Get( *project );
// Add metadata BEFORE writing the header.
// At the moment that works with ffmpeg-git and ffmpeg-0.5 for MP4.

View File

@ -447,7 +447,7 @@ bool ExportFLAC::GetMetadata(AudacityProject *project, const Tags *tags)
{
// Retrieve tags if needed
if (tags == NULL)
tags = project->GetTags();
tags = &Tags::Get( *project );
mMetadata.reset(::FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT));

View File

@ -235,7 +235,7 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
// Put ID3 tags at beginning of file
if (metadata == NULL)
metadata = project->GetTags();
metadata = &Tags::Get( *project );
FileIO outFile(fName, FileIO::Output);
if (!outFile.IsOpened()) {

View File

@ -1868,7 +1868,7 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
// Put ID3 tags at beginning of file
if (metadata == NULL)
metadata = project->GetTags();
metadata = &Tags::Get( *project );
// Open file for writing
wxFFile outFile(fName, wxT("w+b"));

View File

@ -732,7 +732,7 @@ ProgressResult ExportMultiple::ExportMultipleByLabel(bool byName,
/* do the metadata for this file */
// copy project metadata to start with
setting.filetags = *(mProject->GetTags());
setting.filetags = Tags::Get( *mProject );
// over-ride with values
setting.filetags.SetTag(TAG_TITLE, title);
setting.filetags.SetTag(TAG_TRACK, l+1);
@ -849,7 +849,7 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
/* do the metadata for this file */
// copy project metadata to start with
setting.filetags = *(mProject->GetTags());
setting.filetags = Tags::Get( *mProject );
// over-ride with values
setting.filetags.SetTag(TAG_TITLE, title);
setting.filetags.SetTag(TAG_TRACK, l+1);

View File

@ -381,7 +381,7 @@ bool ExportOGG::FillComment(AudacityProject *project, vorbis_comment *comment, c
{
// Retrieve tags from project if not over-ridden
if (metadata == NULL)
metadata = project->GetTags();
metadata = &Tags::Get( *project );
vorbis_comment_init(comment);

View File

@ -503,7 +503,7 @@ ProgressResult ExportPCM::Export(AudacityProject *project,
}
// Retrieve tags if not given a set
if (metadata == NULL)
metadata = project->GetTags();
metadata = &Tags::Get( *project );
// Install the metata at the beginning of the file (except for
// WAV and WAVEX formats)

View File

@ -200,15 +200,19 @@ bool DoEditMetadata
(AudacityProject &project,
const wxString &title, const wxString &shortUndoDescription, bool force)
{
auto tags = project.GetTags();
auto &tags = Tags::Get( project );
// Back up my tags
auto newTags = tags->Duplicate();
// Tags (artist name, song properties, MP3 ID3 info, etc.)
// The structure may be shared with undo history entries
// To keep undo working correctly, always replace this with a NEW duplicate
// BEFORE doing any editing of it!
auto newTags = tags.Duplicate();
if (newTags->ShowEditDialog(&project, title, force)) {
if (*tags != *newTags) {
if (tags != *newTags) {
// Commit the change to project state only now.
project.SetTags( newTags );
Tags::Set( project, newTags );
project.PushState(title, shortUndoDescription);
}
bool bShowInFuture;