18#include "DirManager.h"
19#include "widgets/AudacityMessageBox.h"
22#include "widgets/MultiDialog.h"
23#include "widgets/ProgressDialog.h"
33 DirManager &dm,
const bool bForceError,
const bool bAutoRecoverMode)
35#pragma message( "====================================================================")
36#pragma message( "Don\'t forget to redo ProjectFSCK")
37#pragma message( "====================================================================")
50 if (bForceError && !bAutoRecoverMode)
58 auto msg =
XO(
"Project check read faulty Sequence tags.");
60 XO(
"Close project immediately with no changes"),
61 XO(
"Continue with repairs noted in log, and check for more errors. This will save the project in its current state, unless you \"Close project immediately\" on further error alerts.")
65 XO(
"Warning - Problems Reading Sequence Tags"),
74 auto dirPath = ( dm.GetDataFilesDir() );
75 DirManager::RecursivelyEnumerateWithProgress(
82 XO(
"Inspecting project file data"));
87 MissingAliasFilesDialog::SetShouldShow(
false);
90 dm.FindMissingAliasFiles(missingAliasFilesAUFHash, missingAliasFilesPathHash);
101XO(
"Project check of \"%s\" folder \
102\ndetected %lld missing external audio file(s) \
103\n('aliased files'). There is no way for Audacity \
104\nto recover these files automatically. \
105\n\nIf you choose the first or second option below, \
106\nyou can try to find and restore the missing files \
107\nto their previous location. \
108\n\nNote that for the second option, the waveform \
109\nmay not show silence. \
110\n\nIf you choose the third option, this will save the \
111\nproject in its current state, unless you \"Close \
112\nproject immediately\" on further error alerts.")
115 (
long long) missingAliasFilesPathHash.size() );
117 XO(
"Close project immediately with no changes"),
118 XO(
"Treat missing audio as silence (this session only)"),
119 XO(
"Replace missing audio with silence (permanent immediately)."),
121 wxLog::FlushActive();
123 XO(
"Warning - Missing Aliased File(s)"),
133 BlockHash::iterator iter = missingAliasFilesAUFHash.begin();
134 while (iter != missingAliasFilesAUFHash.end())
137 BlockFilePtr b = iter->second.lock();
140 auto ab =
static_cast< AliasBlockFile *
> ( &*b );
150 ab->ChangeAliasedFileName(std::move(dummy));
157 [&] { ab->Recover(); },
166 ab->SilenceAliasLog();
170 if ((action == 2) && bAutoRecoverMode)
171 wxLogWarning(
wxT(
" Project check replaced missing aliased file(s) with silence."));
181 dm.FindMissingAUFs(missingAUFHash);
186 if (bAutoRecoverMode)
191XO(
"Project check of \"%s\" folder \
192\ndetected %lld missing alias (.auf) blockfile(s). \
193\nAudacity can fully regenerate these files \
194\nfrom the current audio in the project.")
196 dm.GetProjectName(), (
long long) missingAUFHash.size() );
198 XO(
"Regenerate alias summary files (safe and recommended)"),
199 XO(
"Fill in silence for missing display data (this session only)"),
200 XO(
"Close project immediately with no further changes"),
202 wxLog::FlushActive();
204 XO(
"Warning - Missing Alias Summary File(s)"),
214 BlockHash::iterator iter = missingAUFHash.begin();
215 while (iter != missingAUFHash.end())
217 BlockFilePtr b = iter->second.lock();
242 if ((action == 0) && bAutoRecoverMode)
243 wxLogWarning(
wxT(
" Project check regenerated missing alias summary file(s)."));
251 dm.FindMissingAUs(missingAUHash);
256 if (bAutoRecoverMode)
261XO(
"Project check of \"%s\" folder \
262\ndetected %lld missing audio data (.au) blockfile(s), \
263\nprobably due to a bug, system crash, or accidental \
264\ndeletion. There is no way for Audacity to recover \
265\nthese missing files automatically. \
266\n\nIf you choose the first or second option below, \
267\nyou can try to find and restore the missing files \
268\nto their previous location. \
269\n\nNote that for the second option, the waveform \
270\nmay not show silence.")
272 dm.GetProjectName(), (
long long) missingAUHash.size() );
274 XO(
"Close project immediately with no further changes"),
275 XO(
"Treat missing audio as silence (this session only)"),
276 XO(
"Replace missing audio with silence (permanent immediately)"),
278 wxLog::FlushActive();
280 XO(
"Warning - Missing Audio Data Block File(s)"),
282 "Warning_-_Missing_Audio_Data_Block_Files");
290 BlockHash::iterator iter = missingAUHash.begin();
291 while (iter != missingAUHash.end())
293 BlockFilePtr b = iter->second.lock();
318 if ((action == 2) && bAutoRecoverMode)
319 wxLogWarning(
wxT(
" Project check replaced missing audio data block file(s) with silence."));
327 dm.FindOrphanBlockFiles(filePathArray, orphanFilePathArray);
333 if (bAutoRecoverMode)
335 wxLogWarning(
wxT(
" Project check ignored orphan block file(s). They will be deleted when project is saved."));
341XO(
"Project check of \"%s\" folder \
342\nfound %d orphan block file(s). These files are \
343\nunused by this project, but might belong to \
345\nThey are doing no harm and are small.")
346 .Format( dm.GetProjectName(), (
int)orphanFilePathArray.size() );
349 XO(
"Continue without deleting; ignore the extra files this session"),
350 XO(
"Close project immediately with no further changes"),
351 XO(
"Delete orphan files (permanent immediately)"),
353 wxLog::FlushActive();
355 XO(
"Warning - Orphan Block File(s)"),
357 "Warning_-_Orphan_Block_Files"
364 else if (action == 2)
371 for (
const auto &orphan : orphanFilePathArray )
372 wxRemoveFile(orphan);
381 XO(
"Cleaning up unused directories in project data"));
383 int nDirCount = DirManager::RecursivelyCountSubdirs(dirPath) + 1;
384 DirManager::RecursivelyRemoveEmptyDirs(dirPath, nDirCount, &pProgress);
389 !missingAliasFilesAUFHash.empty() ||
390 !missingAUFHash.empty() ||
391 !missingAUHash.empty() ||
392 !orphanFilePathArray.empty())
394 wxLogWarning(
wxT(
"Project check found file inconsistencies inspecting the loaded project data."));
395 wxLog::FlushActive();
398 if (bAutoRecoverMode)
401"Project check found file inconsistencies during automatic recovery.\n\nSelect 'Help > Diagnostics > Show Log...' to see details."),
402 XO(
"Warning: Problems in Automatic Recovery"),
403 wxOK | wxICON_EXCLAMATION);
406 MissingAliasFilesDialog::SetShouldShow(
true);
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), F3 delayedHandler=DefaultDelayedHandlerAction) noexcept(noexcept(handler(std::declval< AudacityException * >())) &&noexcept(handler(nullptr)) &&noexcept(std::function< void(AudacityException *)>{std::move(delayedHandler)}))
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
int ProjectFSCK(DirManager &dm, const bool bForceError, const bool bAutoRecoverMode)
std::vector< TranslatableString > TranslatableStrings
Base class for exceptions specially processed by the application.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
int ShowMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log)
Display a dialog with radio buttons.