Audacity 3.2.0
Classes | Typedefs | Enumerations | Functions
Dependencies.cpp File Reference
#include "Audacity.h"
#include "Dependencies.h"
#include <wx/button.h>
#include <wx/defs.h>
#include <wx/dialog.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 67 of file Dependencies.cpp.

◆ BoolBlockFileHash

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

Definition at line 72 of file Dependencies.cpp.

◆ ReplacedBlockFileHash

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

Definition at line 71 of file Dependencies.cpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
FileListID 
CopySelectedFilesButtonID 
CopyNamesToClipboardID 
FutureActionChoiceID 

Definition at line 287 of file Dependencies.cpp.

287 {
288 FileListID = 6000,
292};
@ CopySelectedFilesButtonID
@ FutureActionChoiceID
@ FileListID
@ CopyNamesToClipboardID

Function Documentation

◆ EVT_BUTTON() [1/2]

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

Definition at line 302 of file Dependencies.cpp.

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

References eIsCreating, and S.

◆ EVT_BUTTON() [2/2]

EVT_BUTTON ( wxID_NO  ,
DependencyDialog::OnNo   
)

◆ FindDependencies()

void FindDependencies ( AudacityProject project,
AliasedFileArray outAliasedFiles 
)

Definition at line 109 of file Dependencies.cpp.

111{
113
114 BlockPtrArray blocks;
115 GetAllSeqBlocks(project, &blocks);
116
117 AliasedFileHash aliasedFileHash;
118 BoolBlockFileHash blockFileHash;
119
120 for (const auto &blockFile : blocks) {
121 const auto &f = blockFile->f;
122 if (f->IsAlias() && (blockFileHash.count( &*f ) == 0))
123 {
124 // f is an alias block we have not yet counted.
125 blockFileHash[ &*f ] = true; // Don't count the same blockfile twice.
126 auto aliasBlockFile = static_cast<AliasBlockFile*>( &*f );
127 const wxFileName &fileName = aliasBlockFile->GetAliasedFileName();
128
129 // In ProjectFSCK(), if the user has chosen to
130 // "Replace missing audio with silence", the code there puts in an empty wxFileName.
131 // Don't count those in dependencies.
132 if (!fileName.IsOk())
133 continue;
134
135 const wxString &fileNameStr = fileName.GetFullPath();
136 auto blockBytes = (SAMPLE_SIZE(format) *
137 aliasBlockFile->GetLength());
138 if (aliasedFileHash.count(fileNameStr) > 0)
139 // Already put this AliasBlockFile in aliasedFileHash.
140 // Update block count.
141 aliasedFileHash[fileNameStr]->mByteCount += blockBytes;
142 else
143 {
144 // Haven't counted this AliasBlockFile yet.
145 // Add to return array and internal hash.
146
147 // PRL: do this in two steps so that we move instead of copying.
148 // We don't have a moving push_back in all compilers.
149 outAliasedFiles.push_back(AliasedFile{});
150 outAliasedFiles.back() =
152 wxFileNameWrapper { fileName },
153 wxLongLong(blockBytes), fileName.FileExists()
154 };
155 aliasedFileHash[fileNameStr] = &outAliasedFiles.back();
156 }
157 }
158 }
159}
std::unordered_map< BlockFile *, bool > BoolBlockFileHash
static void GetAllSeqBlocks(AudacityProject *project, BlockPtrArray *outBlocks)
std::unordered_map< wxString, AliasedFile * > AliasedFileHash
int format
Definition: ExportPCM.cpp:56
sampleFormat
Definition: SampleFormat.h:29
#define SAMPLE_SIZE(SampleFormat)
Definition: SampleFormat.h:44
std::vector< SeqBlock * > BlockPtrArray
Definition: Sequence.h:50
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 format, GetAllSeqBlocks(), 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 77 of file Dependencies.cpp.

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

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 340 of file Dependencies.cpp.

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

References XO.

Referenced by DependencyDialog::PopulateList().

Here is the caller graph for this function:

◆ kStdMsg()

static const TranslatableString kStdMsg ( )
static

Definition at line 333 of file Dependencies.cpp.

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

References XO.

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

Here is the caller graph for this function:

◆ RemoveDependencies()

static void RemoveDependencies ( AudacityProject project,
AliasedFileArray aliasedFiles 
)
static

Definition at line 164 of file Dependencies.cpp.

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

References format, BasicUI::Get(), GetAllSeqBlocks(), 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 95 of file Dependencies.cpp.

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

Referenced by RemoveDependencies().

Here is the caller graph for this function:

◆ ShowDependencyDialogIfNeeded()

bool ShowDependencyDialogIfNeeded ( AudacityProject project,
bool  isSaving 
)

Definition at line 602 of file Dependencies.cpp.

604{
605 auto pWindow = FindProjectFrame( project );
606 AliasedFileArray aliasedFiles;
607 FindDependencies(project, aliasedFiles);
608
609 if (aliasedFiles.empty()) {
610 if (!isSaving)
611 {
612 auto msg =
613XO("Your project is self-contained; it does not depend on any external audio files. \
614\n\nSome older Audacity projects may not be self-contained, and care \n\
615is needed to keep their external dependencies in the right place.\n\
616New projects will be self-contained and are less risky.");
618 msg,
619 XO("Dependency Check"),
620 wxOK | wxICON_INFORMATION,
621 pWindow);
622 }
623 return true; // Nothing to do.
624 }
625
626 if (isSaving)
627 {
628 RemoveDependencies(project, aliasedFiles);
629 return true;
630 }
631
632 DependencyDialog dlog(pWindow, -1, project, aliasedFiles, isSaving);
633 int returnCode = dlog.ShowModal();
634 if (returnCode == wxID_CANCEL)
635 return false;
636 else if (returnCode == wxID_YES)
637 RemoveDependencies(project, aliasedFiles);
638
639 return true;
640}
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(), RemoveDependencies(), and XO.

Here is the call graph for this function: