35{
36#pragma message( "====================================================================")
37#pragma message( "Don\'t forget to redo ProjectFSCK")
38#pragma message( "====================================================================")
39
40
41
42
43
44
45
46
47
48 int action;
49 int nResult = 0;
50
51 if (bForceError && !bAutoRecoverMode)
52 {
53
54
55
56
57
58
59 auto msg =
XO(
"Project check read faulty Sequence tags.");
61 XO(
"Close project immediately with no changes"),
62 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.")
63 };
64 wxLog::FlushActive();
66 XO(
"Warning - Problems Reading Sequence Tags"),
67 buttons,"");
68 if (action == 0)
70 else
72 }
73#if 0
75 auto dirPath = ( dm.GetDataFilesDir() );
76 DirManager::RecursivelyEnumerateWithProgress(
77 dirPath,
78 filePathArray,
79 wxEmptyString,
80 wxEmptyString,
81 true, false,
82 dm.NumBlockFiles(),
83 XO(
"Inspecting project file data"));
84
85
86
87
88 MissingAliasFilesDialog::SetShouldShow(false);
89 BlockHash missingAliasFilesAUFHash;
90 BlockHash missingAliasFilesPathHash;
91 dm.FindMissingAliasFiles(missingAliasFilesAUFHash, missingAliasFilesPathHash);
92
94 {
95
96
97 if (bAutoRecoverMode)
98 action = 2;
99 else
100 {
101 auto msg =
102XO(
"Project check of \"%s\" folder \
103\ndetected %lld missing external audio file(s) \
104\n('aliased files'). There is no way for Audacity \
105\nto recover these files automatically. \
106\n\nIf you choose the first or second option below, \
107\nyou can try to find and restore the missing files \
108\nto their previous location. \
109\n\nNote that for the second option, the waveform \
110\nmay not show silence. \
111\n\nIf you choose the third option, this will save the \
112\nproject in its current state, unless you \"Close \
113\nproject immediately\" on further error alerts.")
114 .Format(
115 dm.GetProjectName(),
116 (long long) missingAliasFilesPathHash.size() );
118 XO(
"Close project immediately with no changes"),
119 XO(
"Treat missing audio as silence (this session only)"),
120 XO(
"Replace missing audio with silence (permanent immediately)."),
121 };
122 wxLog::FlushActive();
124 XO(
"Warning - Missing Aliased File(s)"),
125 buttons,
126 "");
127 }
128
129 if (action == 0)
131 else
132 {
133
134 BlockHash::iterator iter = missingAliasFilesAUFHash.begin();
135 while (iter != missingAliasFilesAUFHash.end())
136 {
137
138 BlockFilePtr b = iter->second.lock();
139 wxASSERT(b);
140 if (b) {
141 auto ab = static_cast< AliasBlockFile * > ( &*b );
142
143 if (action == 2)
144 {
145
146
147
148
150 dummy.Clear();
151 ab->ChangeAliasedFileName(std::move(dummy));
152
153
154
155
156
158 [&] { ab->Recover(); },
160 );
161
163 }
164
165 if (action == 1)
166
167 ab->SilenceAliasLog();
168 }
169 ++iter;
170 }
171 if ((action == 2) && bAutoRecoverMode)
172 wxLogWarning(wxT(" Project check replaced missing aliased file(s) with silence."));
173 }
174 }
175
176
177
178
179
180
181 BlockHash missingAUFHash;
182 dm.FindMissingAUFs(missingAUFHash);
184 {
185
186
187 if (bAutoRecoverMode)
188 action = 0;
189 else
190 {
191 auto msg =
192XO(
"Project check of \"%s\" folder \
193\ndetected %lld missing alias (.auf) blockfile(s). \
194\nAudacity can fully regenerate these files \
195\nfrom the current audio in the project.")
196 .Format(
197 dm.GetProjectName(), (long long) missingAUFHash.size() );
199 XO(
"Regenerate alias summary files (safe and recommended)"),
200 XO(
"Fill in silence for missing display data (this session only)"),
201 XO(
"Close project immediately with no further changes"),
202 };
203 wxLog::FlushActive();
205 XO(
"Warning - Missing Alias Summary File(s)"),
206 buttons,
207 "");
208 }
209
210 if (action == 2)
212 else
213 {
214
215 BlockHash::iterator iter = missingAUFHash.begin();
216 while (iter != missingAUFHash.end())
217 {
218 BlockFilePtr b = iter->second.lock();
219 wxASSERT(b);
220 if (b) {
221 if(action==0) {
222
223
224
225
226
228 [&] {
229 b->Recover();
231 },
233 );
234 }
235
236 if (action==1){
237
238 b->SilenceLog();
239 }
240 }
241 ++iter;
242 }
243 if ((action == 0) && bAutoRecoverMode)
244 wxLogWarning(wxT(" Project check regenerated missing alias summary file(s)."));
245 }
246 }
247
248
249
250
251 BlockHash missingAUHash;
252 dm.FindMissingAUs(missingAUHash);
254 {
255
256
257 if (bAutoRecoverMode)
258 action = 2;
259 else
260 {
261 auto msg =
262XO(
"Project check of \"%s\" folder \
263\ndetected %lld missing audio data (.au) blockfile(s), \
264\nprobably due to a bug, system crash, or accidental \
265\ndeletion. There is no way for Audacity to recover \
266\nthese missing files automatically. \
267\n\nIf you choose the first or second option below, \
268\nyou can try to find and restore the missing files \
269\nto their previous location. \
270\n\nNote that for the second option, the waveform \
271\nmay not show silence.")
272 .Format(
273 dm.GetProjectName(), (long long) missingAUHash.size() );
275 XO(
"Close project immediately with no further changes"),
276 XO(
"Treat missing audio as silence (this session only)"),
277 XO(
"Replace missing audio with silence (permanent immediately)"),
278 };
279 wxLog::FlushActive();
281 XO(
"Warning - Missing Audio Data Block File(s)"),
282 buttons,
283 "Warning_-_Missing_Audio_Data_Block_Files");
284 }
285
286 if (action == 0)
288 else
289 {
290
291 BlockHash::iterator iter = missingAUHash.begin();
292 while (iter != missingAUHash.end())
293 {
294 BlockFilePtr b = iter->second.lock();
295 wxASSERT(b);
296 if (b) {
297 if (action == 2)
298 {
299
300
301
302
303
305 [&] {
306
307 b->Recover();
309 },
311 );
312 }
313
314 if (action == 1)
315 b->SilenceLog();
316 }
317 ++iter;
318 }
319 if ((action == 2) && bAutoRecoverMode)
320 wxLogWarning(wxT(" Project check replaced missing audio data block file(s) with silence."));
321 }
322 }
323
324
325
326
328 dm.FindOrphanBlockFiles(filePathArray, orphanFilePathArray);
329
331 {
332
333
334 if (bAutoRecoverMode)
335 {
336 wxLogWarning(wxT(" Project check ignored orphan block file(s). They will be deleted when project is saved."));
337 action = 1;
338 }
339 else
340 {
341 auto msg =
342XO(
"Project check of \"%s\" folder \
343\nfound %d orphan block file(s). These files are \
344\nunused by this project, but might belong to \
345other projects. \
346\nThey are doing no harm and are small.")
347 .Format( dm.GetProjectName(), (int)orphanFilePathArray.size() );
348
350 XO(
"Continue without deleting; ignore the extra files this session"),
351 XO(
"Close project immediately with no further changes"),
352 XO(
"Delete orphan files (permanent immediately)"),
353 };
354 wxLog::FlushActive();
356 XO(
"Warning - Orphan Block File(s)"),
357 buttons,
358 "Warning_-_Orphan_Block_Files"
359 );
360 }
361
362 if (action == 1)
364
365 else if (action == 2)
366 {
367
368
369
370
371
372 for ( const auto &orphan : orphanFilePathArray )
373 wxRemoveFile(orphan);
374 }
375 }
376
378 {
379
382 XO(
"Cleaning up unused directories in project data"));
383
384 int nDirCount = DirManager::RecursivelyCountSubdirs(dirPath) + 1;
385 DirManager::RecursivelyRemoveEmptyDirs(dirPath, nDirCount, &pProgress);
386 }
387
388
389 if (bForceError ||
390 !missingAliasFilesAUFHash.empty() ||
391 !missingAUFHash.empty() ||
392 !missingAUHash.empty() ||
393 !orphanFilePathArray.empty())
394 {
395 wxLogWarning(wxT("Project check found file inconsistencies inspecting the loaded project data."));
396 wxLog::FlushActive();
397
398
399 if (bAutoRecoverMode)
402"Project check found file inconsistencies during automatic recovery.\n\nSelect 'Help > Diagnostics > Show Log...' to see details."),
403 XO(
"Warning: Problems in Automatic Recovery"),
404 wxOK | wxICON_EXCLAMATION);
405 }
406
407 MissingAliasFilesDialog::SetShouldShow(true);
408#endif
409 return nResult;
410}
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 ShowMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log)
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.