Audacity 3.2.0
Classes | Typedefs | Enumerations | Functions
Dependencies.cpp File Reference
#include "Audacity.h"
#include "Dependencies.h"
#include <wx/defs.h>
#include <wx/filename.h>
#include <wx/listctrl.h>
#include <wx/menu.h>
#include <wx/choice.h>
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#include <wx/frame.h>
#include <wx/stattext.h>
#include "blockfile/SimpleBlockFile.h"
#include "DirManager.h"
#include "FileFormats.h"
#include "Prefs.h"
#include "Project.h"
#include "Sequence.h"
#include "ShuttleGui.h"
#include "WaveTrack.h"
#include "WaveClip.h"
#include "prefs/QualityPrefs.h"
#include "widgets/AudacityMessageBox.h"
#include "widgets/ProgressDialog.h"
#include <unordered_map>
Include dependency graph for Dependencies.cpp:

Go to the source code of this file.

Classes

class  DependencyDialog
 DependencyDialog shows dependencies of an AudacityProject on AliasedFile s. More...
 

Typedefs

using AliasedFileHash = std::unordered_map< wxString, AliasedFile * >
 
using ReplacedBlockFileHash = std::unordered_map< BlockFile *, BlockFilePtr >
 
using BoolBlockFileHash = std::unordered_map< BlockFile *, bool >
 

Enumerations

enum  { FileListID = 6000 , CopySelectedFilesButtonID , CopyNamesToClipboardID , FutureActionChoiceID }
 

Functions

static void GetAllSeqBlocks (AudacityProject *project, BlockPtrArray *outBlocks)
 
static void ReplaceBlockFiles (BlockPtrArray &blocks, ReplacedBlockFileHash &hash)
 
void FindDependencies (AudacityProject *project, AliasedFileArray &outAliasedFiles)
 
static void RemoveDependencies (AudacityProject *project, AliasedFileArray &aliasedFiles)
 
 EVT_BUTTON (wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
 
DependencyDialog::OnYes EVT_BUTTON (wxID_CANCEL, DependencyDialog::OnCancel) DependencyDialog
 
static const TranslatableString kStdMsg ()
 
static const TranslatableString kExtraMsgForMissingFiles ()
 
bool ShowDependencyDialogIfNeeded (AudacityProject *project, bool isSaving)
 

Typedef Documentation

◆ AliasedFileHash

using AliasedFileHash = std::unordered_map<wxString, AliasedFile*>

Definition at line 65 of file Dependencies.cpp.

◆ BoolBlockFileHash

using BoolBlockFileHash = std::unordered_map<BlockFile *, bool>

Definition at line 70 of file Dependencies.cpp.

◆ ReplacedBlockFileHash

using ReplacedBlockFileHash = std::unordered_map<BlockFile *, BlockFilePtr>

Definition at line 69 of file Dependencies.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
FileListID 
CopySelectedFilesButtonID 
CopyNamesToClipboardID 
FutureActionChoiceID 

Definition at line 285 of file Dependencies.cpp.

285 {
286 FileListID = 6000,
290};
@ CopySelectedFilesButtonID
@ FutureActionChoiceID
@ FileListID
@ CopyNamesToClipboardID

Function Documentation

◆ EVT_BUTTON() [1/2]

DependencyDialog::OnYes EVT_BUTTON ( wxID_CANCEL  ,
DependencyDialog::OnCancel   
)

Definition at line 300 of file Dependencies.cpp.

309: wxDialogWrapper(parent, id, XO("Project Depends on Other Audio Files"),
310 wxDefaultPosition, wxDefaultSize,
311 (isSaving ?
312 (wxDEFAULT_DIALOG_STYLE & ~wxCLOSE_BOX) : // no close box when saving
313 wxDEFAULT_DIALOG_STYLE) |
314 wxRESIZE_BORDER),
315 mProject(project),
316 mAliasedFiles(aliasedFiles),
317 mIsSaving(isSaving),
318 mHasMissingFiles(false),
319 mHasNonMissingFiles(false),
320 mMessageStaticText(NULL),
321 mFileListCtrl(NULL),
322 mCopySelectedFilesButton(NULL),
323 mCopyAllFilesButton(NULL),
324 mFutureActionChoice(NULL)
325{
326 SetName();
327 ShuttleGui S(this, eIsCreating);
328 PopulateOrExchange(S);
329}
XO("Cut/Copy/Paste")
@ eIsCreating
Definition: ShuttleGui.h:37
const auto project
#define S(N)
Definition: ToChars.cpp:64
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640

References eIsCreating, and S.

◆ EVT_BUTTON() [2/2]

EVT_BUTTON ( wxID_NO  ,
DependencyDialog::OnNo   
)

◆ FindDependencies()

void FindDependencies ( AudacityProject project,
AliasedFileArray outAliasedFiles 
)

Definition at line 107 of file Dependencies.cpp.

109{
111
112 BlockPtrArray blocks;
113 GetAllSeqBlocks(project, &blocks);
114
115 AliasedFileHash aliasedFileHash;
116 BoolBlockFileHash blockFileHash;
117
118 for (const auto &blockFile : blocks) {
119 const auto &f = blockFile->f;
120 if (f->IsAlias() && (blockFileHash.count( &*f ) == 0))
121 {
122 // f is an alias block we have not yet counted.
123 blockFileHash[ &*f ] = true; // Don't count the same blockfile twice.
124 auto aliasBlockFile = static_cast<AliasBlockFile*>( &*f );
125 const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
126
127 // In ProjectFSCK(), if the user has chosen to
128 // "Replace missing audio with silence", the code there puts in an empty wxFileName.
129 // Don't count those in dependencies.
130 if (!fileName.IsOk())
131 continue;
132
133 const wxString &fileNameStr = fileName.GetFullPath();
134 auto blockBytes = (SAMPLE_SIZE(format) *
135 aliasBlockFile->GetLength());
136 if (aliasedFileHash.count(fileNameStr) > 0)
137 // Already put this AliasBlockFile in aliasedFileHash.
138 // Update block count.
139 aliasedFileHash[fileNameStr]->mByteCount += blockBytes;
140 else
141 {
142 // Haven't counted this AliasBlockFile yet.
143 // Add to return array and internal hash.
144
145 // PRL: do this in two steps so that we move instead of copying.
146 // We don't have a moving push_back in all compilers.
147 outAliasedFiles.push_back(AliasedFile{});
148 outAliasedFiles.back() =
150 wxFileNameWrapper { fileName },
151 wxLongLong(blockBytes), fileName.FileExists()
152 };
153 aliasedFileHash[fileNameStr] = &outAliasedFiles.back();
154 }
155 }
156 }
157}
std::unordered_map< BlockFile *, bool > BoolBlockFileHash
static void GetAllSeqBlocks(AudacityProject *project, BlockPtrArray *outBlocks)
std::unordered_map< wxString, AliasedFile * > AliasedFileHash
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:52
std::deque< SeqBlock * > BlockPtrArray
Definition: Sequence.h:51
An audio file that is referenced (pointed into) directly from an Audacity .aup file rather than Audac...
Definition: Dependencies.h:24
PROJECT_RATE_API sampleFormat SampleFormatChoice()

References anonymous_namespace{ExportPCM.cpp}::format, GetAllSeqBlocks(), project, SAMPLE_SIZE, and QualitySettings::SampleFormatChoice().

Referenced by ShowDependencyDialogIfNeeded().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetAllSeqBlocks()

static void GetAllSeqBlocks ( AudacityProject project,
BlockPtrArray outBlocks 
)
static

Definition at line 75 of file Dependencies.cpp.

77{
78 for (auto waveTrack : TrackList::Get( *project ).Any< WaveTrack >()) {
79 for(const auto &clip : waveTrack->GetAllClips()) {
80 Sequence *sequence = clip->GetSequence();
81 BlockArray &blocks = sequence->GetBlockArray();
82 for (size_t i = 0; i < blocks.size(); i++)
83 outBlocks->push_back(&blocks[i]);
84 }
85 }
86}
A WaveTrack contains WaveClip(s). A WaveClip contains a Sequence. A Sequence is primarily an interfac...
Definition: Sequence.h:53
const BlockArray & GetBlockArray() const
Definition: Sequence.h:231
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:950
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:314
A Track that contains audio waveform data.
Definition: WaveTrack.h:203

References TrackList::Any(), TrackList::Get(), and Sequence::GetBlockArray().

Referenced by FindDependencies(), and RemoveDependencies().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ kExtraMsgForMissingFiles()

static const TranslatableString kExtraMsgForMissingFiles ( )
static

Definition at line 338 of file Dependencies.cpp.

339{
340 return
341XO("\n\nFiles shown as MISSING have been moved or deleted and cannot be copied.\
342\nRestore them to their original location to be able to copy into project.");
343}

References XO().

Referenced by DependencyDialog::PopulateList().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ kStdMsg()

static const TranslatableString kStdMsg ( )
static

Definition at line 331 of file Dependencies.cpp.

332{
333 return
334XO("Copying these files into your project will remove this dependency.\
335\nThis is safer, but needs more disk space.");
336}

References XO().

Referenced by DependencyDialog::PopulateList(), and DependencyDialog::PopulateOrExchange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveDependencies()

static void RemoveDependencies ( AudacityProject project,
AliasedFileArray aliasedFiles 
)
static

Definition at line 162 of file Dependencies.cpp.

165{
166 auto &dirManager = DirManager::Get( *project );
167
168 ProgressDialog progress(
169 XO("Removing Dependencies"),
170 XO("Copying audio data into project..."));
171 auto updateResult = ProgressResult::Success;
172
173 // Hash aliasedFiles based on their full paths and
174 // count total number of bytes to process.
175 AliasedFileHash aliasedFileHash;
176 wxLongLong totalBytesToProcess = 0;
177 for (auto &aliasedFile : aliasedFiles) {
178 totalBytesToProcess += aliasedFile.mByteCount;
179 const wxString &fileNameStr = aliasedFile.mFileName.GetFullPath();
180 aliasedFileHash[fileNameStr] = &aliasedFile;
181 }
182
183 BlockPtrArray blocks;
184 GetAllSeqBlocks(project, &blocks);
185
187 ReplacedBlockFileHash blockFileHash;
188 wxLongLong completedBytes = 0;
189 for (const auto blockFile : blocks) {
190 const auto &f = blockFile->f;
191 if (f->IsAlias() && (blockFileHash.count( &*f ) == 0))
192 {
193 // f is an alias block we have not yet processed.
194 auto aliasBlockFile = static_cast<AliasBlockFile*>( &*f );
195 const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
196 const wxString &fileNameStr = fileName.GetFullPath();
197
198 if (aliasedFileHash.count(fileNameStr) == 0)
199 // This aliased file was not selected to be replaced. Skip it.
200 continue;
201
202 // Convert it from an aliased file to an actual file in the project.
203 auto len = aliasBlockFile->GetLength();
204 BlockFilePtr newBlockFile;
205 {
206 SampleBuffer buffer(len, format);
207 // We tolerate exceptions from NewBlockFile
208 // and so we can allow exceptions from ReadData too
209 f->ReadData(buffer.ptr(), format, 0, len);
210 newBlockFile =
211 dirManager.NewBlockFile( [&]( wxFileNameWrapper filePath ) {
212 return make_blockfile<SimpleBlockFile>(
213 std::move(filePath), buffer.ptr(), len, format);
214 } );
215 }
216
217 // Update our hash so we know what block files we've done
218 blockFileHash[ &*f ] = newBlockFile;
219
220 // Update the progress bar
221 completedBytes += SAMPLE_SIZE(format) * len;
222 updateResult = progress.Update(completedBytes, totalBytesToProcess);
223 if (updateResult != ProgressResult::Success)
224 // leave the project unchanged
225 return;
226 }
227 }
228
229 // COMMIT OPERATIONS needing NOFAIL-GUARANTEE:
230
231 // Above, we created a SimpleBlockFile contained in our project
232 // to go with each AliasBlockFile that we wanted to migrate.
233 // However, that didn't actually change any references to these
234 // blockfiles in the Sequences, so we do that next...
235 ReplaceBlockFiles(blocks, blockFileHash);
236}
static void ReplaceBlockFiles(BlockPtrArray &blocks, ReplacedBlockFileHash &hash)
std::unordered_map< BlockFile *, BlockFilePtr > ReplacedBlockFileHash
ProgressDialog Class.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:202

References anonymous_namespace{ExportPCM.cpp}::format, BasicUI::Get(), GetAllSeqBlocks(), project, SampleBuffer::ptr(), ReplaceBlockFiles(), SAMPLE_SIZE, QualitySettings::SampleFormatChoice(), BasicUI::Success, ProgressDialog::Update(), and XO().

Referenced by DependencyDialog::OnCopySelectedFiles(), and ShowDependencyDialogIfNeeded().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReplaceBlockFiles()

static void ReplaceBlockFiles ( BlockPtrArray blocks,
ReplacedBlockFileHash hash 
)
static

Definition at line 93 of file Dependencies.cpp.

96{
97 for (const auto &pBlock : blocks) {
98 auto &f = pBlock->f;
99 const auto src = &*f;
100 if (hash.count( src ) > 0) {
101 const auto &dst = hash[src];
102 f = dst;
103 }
104 }
105}

Referenced by RemoveDependencies().

Here is the caller graph for this function:

◆ ShowDependencyDialogIfNeeded()

bool ShowDependencyDialogIfNeeded ( AudacityProject project,
bool  isSaving 
)

Definition at line 600 of file Dependencies.cpp.

602{
603 auto pWindow = FindProjectFrame( project );
604 AliasedFileArray aliasedFiles;
605 FindDependencies(project, aliasedFiles);
606
607 if (aliasedFiles.empty()) {
608 if (!isSaving)
609 {
610 auto msg =
611XO("Your project is self-contained; it does not depend on any external audio files. \
612\n\nSome older Audacity projects may not be self-contained, and care \n\
613is needed to keep their external dependencies in the right place.\n\
614New projects will be self-contained and are less risky.");
616 msg,
617 XO("Dependency Check"),
618 wxOK | wxICON_INFORMATION,
619 pWindow);
620 }
621 return true; // Nothing to do.
622 }
623
624 if (isSaving)
625 {
626 RemoveDependencies(project, aliasedFiles);
627 return true;
628 }
629
630 DependencyDialog dlog(pWindow, -1, project, aliasedFiles, isSaving);
631 int returnCode = dlog.ShowModal();
632 if (returnCode == wxID_CANCEL)
633 return false;
634 else if (returnCode == wxID_YES)
635 RemoveDependencies(project, aliasedFiles);
636
637 return true;
638}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
static void RemoveDependencies(AudacityProject *project, AliasedFileArray &aliasedFiles)
void FindDependencies(AudacityProject *project, AliasedFileArray &outAliasedFiles)
std::list< AliasedFile > AliasedFileArray
Definition: Dependencies.h:52
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null,...
DependencyDialog shows dependencies of an AudacityProject on AliasedFile s.

References AudacityMessageBox(), FindDependencies(), FindProjectFrame(), project, RemoveDependencies(), and XO().

Here is the call graph for this function: