Audacity 3.2.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
AutoRecoveryDialog Class Referencefinal
Inheritance diagram for AutoRecoveryDialog:
[legend]
Collaboration diagram for AutoRecoveryDialog:
[legend]

Public Member Functions

 AutoRecoveryDialog (AudacityProject *proj)
 
bool HasRecoverables () const
 
FilePaths GetRecoverables ()
 
- Public Member Functions inherited from wxDialogWrapper
 wxDialogWrapper ()
 
 wxDialogWrapper (wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const TranslatableString &name=XO("Dialog"))
 
bool Create (wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const TranslatableString &name=XO("Dialog"))
 
void SetTitle (const TranslatableString &title)
 
void SetLabel (const TranslatableString &title)
 
void SetName (const TranslatableString &title)
 
void SetName ()
 
- Public Member Functions inherited from wxTabTraversalWrapper< wxDialog >
 wxTabTraversalWrapper (Args &&... args)
 
 wxTabTraversalWrapper (const wxTabTraversalWrapper &)=delete
 
 wxTabTraversalWrapper (wxTabTraversalWrapper &&)=delete
 
wxTabTraversalWrapperoperator= (const wxTabTraversalWrapper &)=delete
 
wxTabTraversalWrapperoperator= (wxTabTraversalWrapper &&)=delete
 

Private Member Functions

void PopulateOrExchange (ShuttleGui &S)
 
void PopulateList ()
 
bool HaveChecked ()
 
void OnQuitAudacity (wxCommandEvent &evt)
 
void OnDiscardSelected (wxCommandEvent &evt)
 
void OnRecoverSelected (wxCommandEvent &evt)
 
void OnSkip (wxCommandEvent &evt)
 
void OnColumnClicked (wxListEvent &evt)
 
void OnItemActivated (wxListEvent &evt)
 
void OnListKeyDown (wxKeyEvent &evt)
 

Private Attributes

FilePaths mFiles
 
wxListCtrl * mFileList
 
AudacityProjectmProject
 

Detailed Description

Definition at line 36 of file AutoRecoveryDialog.cpp.

Constructor & Destructor Documentation

◆ AutoRecoveryDialog()

AutoRecoveryDialog::AutoRecoveryDialog ( AudacityProject proj)
explicit

Definition at line 74 of file AutoRecoveryDialog.cpp.

75: wxDialogWrapper(nullptr, wxID_ANY, XO("Automatic Crash Recovery"),
76 wxDefaultPosition, wxDefaultSize,
77 (wxDEFAULT_DIALOG_STYLE & (~wxCLOSE_BOX)) | wxRESIZE_BORDER), // no close box
79{
80 SetName();
83}
XO("Cut/Copy/Paste")
@ eIsCreating
Definition: ShuttleGui.h:37
const auto project
#define S(N)
Definition: ToChars.cpp:64
void PopulateOrExchange(ShuttleGui &S)
AudacityProject * mProject
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640

References eIsCreating, and S.

Member Function Documentation

◆ GetRecoverables()

FilePaths AutoRecoveryDialog::GetRecoverables ( )

Definition at line 90 of file AutoRecoveryDialog.cpp.

91{
92 return mFiles;
93}

References mFiles.

Referenced by ShowAutoRecoveryDialogIfNeeded().

Here is the caller graph for this function:

◆ HasRecoverables()

bool AutoRecoveryDialog::HasRecoverables ( ) const

Definition at line 85 of file AutoRecoveryDialog.cpp.

86{
87 return mFiles.size() > 0;
88}

References mFiles.

Referenced by ShowAutoRecoveryDialogIfNeeded().

Here is the caller graph for this function:

◆ HaveChecked()

bool AutoRecoveryDialog::HaveChecked ( )
private

Definition at line 210 of file AutoRecoveryDialog.cpp.

211{
212 long item = -1;
213 while (true)
214 {
215 item = mFileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
216 if (item == wxNOT_FOUND)
217 {
218 break;
219 }
220 if (mFileList->IsItemChecked(item))
221 {
222 return true;
223 }
224 }
225
226 AudacityMessageBox(XO("No projects selected"), XO("Automatic Crash Recovery"));
227
228 return false;
229}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)

References AudacityMessageBox(), mFileList, and XO().

Referenced by OnDiscardSelected(), and OnRecoverSelected().

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

◆ OnColumnClicked()

void AutoRecoveryDialog::OnColumnClicked ( wxListEvent &  evt)
private

Definition at line 359 of file AutoRecoveryDialog.cpp.

360{
361 if (evt.GetColumn() != 0)
362 {
363 return;
364 }
365
366 long item = -1;
367 while (true)
368 {
369 item = mFileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
370 if (item == wxNOT_FOUND)
371 {
372 break;
373 }
374 mFileList->CheckItem(item, !mFileList->IsItemChecked(item));
375 }
376}

References mFileList.

◆ OnDiscardSelected()

void AutoRecoveryDialog::OnDiscardSelected ( wxCommandEvent &  evt)
private

Definition at line 236 of file AutoRecoveryDialog.cpp.

237{
238 if (!HaveChecked())
239 {
240 return;
241 }
242
243 long item = -1;
244 bool selectedTemporary = false;
245 while (!selectedTemporary)
246 {
247 item = mFileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
248 if (item == wxNOT_FOUND)
249 break;
250 if (!mFileList->IsItemChecked(item))
251 continue;
252 FilePath fileName = mFiles[item];
253 wxFileName file(fileName);
254 if (file.GetExt().IsSameAs(FileNames::UnsavedProjectExtension()))
255 selectedTemporary = true;
256 }
257
258 // Don't give this warning message if all of the checked items are
259 // previously saved, non-temporary projects.
260 if (selectedTemporary) {
261 int ret = AudacityMessageBox(
262 XO("Are you sure you want to discard the selected projects?\n\n"
263 "Choosing \"Yes\" permanently deletes the selected projects immediately."),
264 XO("Automatic Crash Recovery"),
265 wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT, this);
266
267 if (ret == wxNO)
268 return;
269 }
270
271 item = -1;
272 FilePaths files;
273 while (true)
274 {
275 item = mFileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
276 if (item == wxNOT_FOUND)
277 {
278 break;
279 }
280 if (!mFileList->IsItemChecked(item))
281 {
282 // Keep in list
283 files.push_back(mFiles[item]);
284 continue;
285 }
286 FilePath fileName = mFiles[item];
287
288 // Only remove it from disk if it appears to be a temporary file.
289 wxFileName file(fileName);
290 if (file.GetExt().IsSameAs(FileNames::UnsavedProjectExtension()))
291 {
292 file.SetFullName(wxT(""));
293
294 wxFileName temp(TempDirectory::TempDir(), wxT(""));
295 if (file == temp)
297 }
298 else
299 // Don't remove from disk, but do (later) open the database
300 // of this saved file, and discard edits
301 files.push_back(fileName);
302
303 // Forget all about it
304 ActiveProjects::Remove(fileName);
305 }
306
307 PopulateList();
308
309 mFiles = files;
310
311 if (mFileList->GetItemCount() == 0)
312 {
313 EndModal(ID_DISCARD_SELECTED);
314 }
315}
wxT("CloseDown"))
@ ID_DISCARD_SELECTED
wxString FilePath
Definition: Project.h:21
static bool RemoveProject(const FilePath &filename)
Remove any files associated with a project at given path; return true if successful.
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
PROJECT_FILE_IO_API void Remove(const FilePath &path)
FILES_API wxString UnsavedProjectExtension()
FILES_API wxString TempDir()

References AudacityMessageBox(), HaveChecked(), ID_DISCARD_SELECTED, mFileList, mFiles, PopulateList(), ActiveProjects::Remove(), ProjectFileIO::RemoveProject(), TempDirectory::TempDir(), FileNames::UnsavedProjectExtension(), wxT(), and XO().

Here is the call graph for this function:

◆ OnItemActivated()

void AutoRecoveryDialog::OnItemActivated ( wxListEvent &  evt)
private

Definition at line 378 of file AutoRecoveryDialog.cpp.

379{
380 long item = evt.GetIndex();
381 mFileList->CheckItem(item, !mFileList->IsItemChecked(item));
382}

References mFileList.

◆ OnListKeyDown()

void AutoRecoveryDialog::OnListKeyDown ( wxKeyEvent &  evt)
private

Definition at line 384 of file AutoRecoveryDialog.cpp.

385{
386 switch (evt.GetKeyCode())
387 {
388 case WXK_SPACE:
389 {
390 bool selected = false;
391 long item = -1;
392 while (true)
393 {
394 item = mFileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
395 if (item == wxNOT_FOUND)
396 {
397 break;
398 }
399
400 mFileList->CheckItem(item, !mFileList->IsItemChecked(item));
401 }
402 }
403 break;
404
405 case WXK_RETURN:
406 // Don't know why wxListCtrls prevent default dialog action,
407 // but they do, so handle it.
408 EmulateButtonClickIfPresent(GetAffirmativeId());
409 break;
410
411 default:
412 evt.Skip();
413 break;
414 }
415}

References mFileList.

Referenced by PopulateOrExchange().

Here is the caller graph for this function:

◆ OnQuitAudacity()

void AutoRecoveryDialog::OnQuitAudacity ( wxCommandEvent &  evt)
private

Definition at line 231 of file AutoRecoveryDialog.cpp.

232{
233 EndModal(ID_QUIT_AUDACITY);
234}
@ ID_QUIT_AUDACITY

References ID_QUIT_AUDACITY.

◆ OnRecoverSelected()

void AutoRecoveryDialog::OnRecoverSelected ( wxCommandEvent &  evt)
private

Definition at line 317 of file AutoRecoveryDialog.cpp.

318{
319 if (!HaveChecked())
320 {
321 return;
322 }
323
324 FilePaths files;
325
326 bool selected = false;
327 long item = -1;
328 while (true)
329 {
330 item = mFileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE);
331 if (item == wxNOT_FOUND)
332 {
333 if (!selected)
334 {
335 AudacityMessageBox(XO("No projects selected"), XO("Automatic Crash Recovery"));
336 }
337 break;
338 }
339 selected = true;
340
341 if (!mFileList->IsItemChecked(item))
342 {
343 continue;
344 }
345
346 files.push_back(mFiles[item]);
347 }
348
349 mFiles = files;
350
351 EndModal(ID_RECOVER_SELECTED);
352}
@ ID_RECOVER_SELECTED

References AudacityMessageBox(), HaveChecked(), ID_RECOVER_SELECTED, mFileList, mFiles, and XO().

Here is the call graph for this function:

◆ OnSkip()

void AutoRecoveryDialog::OnSkip ( wxCommandEvent &  evt)
private

Definition at line 354 of file AutoRecoveryDialog.cpp.

355{
356 EndModal(ID_SKIP);
357}

References ID_SKIP.

◆ PopulateList()

void AutoRecoveryDialog::PopulateList ( )
private

Definition at line 147 of file AutoRecoveryDialog.cpp.

148{
149 wxString tempdir = TempDirectory::TempDir();
150 wxString pattern = wxT("*.") + FileNames::UnsavedProjectExtension();
151 FilePaths files;
152
153 wxDir::GetAllFiles(tempdir, &files, pattern, wxDIR_FILES);
154
156
157 for (auto file : active)
158 {
159 wxFileName fn = file;
160 if (fn.FileExists())
161 {
162 FilePath fullPath = fn.GetFullPath();
163 if (files.Index(fullPath) == wxNOT_FOUND)
164 {
165 files.push_back(fullPath);
166 }
167 }
168 else
169 {
171 }
172 }
173
174 FilePath activeFile;
175 if (mProject)
176 {
177 auto &projectFileIO = ProjectFileIO::Get(*mProject);
178 activeFile = projectFileIO.GetFileName();
179 }
180
181 mFiles.clear();
182 mFileList->DeleteAllItems();
183 long item = 0;
184
185 for (auto file : files)
186 {
187 wxFileName fn = file;
188 if (fn != activeFile)
189 {
190 mFiles.push_back(fn.GetFullPath());
191 mFileList->InsertItem(item, wxT(""));
192 mFileList->SetItem(item, 1, fn.GetName());
193 mFileList->CheckItem(item, true);
194 item++;
195 }
196 }
197 mFileList->SetMinSize(mFileList->GetBestSize());
198 mFileList->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
199 mFileList->SetColumnWidth(1, 500);
200
201 if (item)
202 {
203 mFileList->SetItemState(0,
204 wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED,
205 wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED);
206 mFileList->SetFocus();
207 }
208}
static const auto fn
static ProjectFileIO & Get(AudacityProject &project)
PROJECT_FILE_IO_API FilePaths GetAll()

References fn, ProjectFileIO::Get(), ActiveProjects::GetAll(), mFileList, mFiles, mProject, ActiveProjects::Remove(), TempDirectory::TempDir(), FileNames::UnsavedProjectExtension(), and wxT().

Referenced by OnDiscardSelected(), and PopulateOrExchange().

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

◆ PopulateOrExchange()

void AutoRecoveryDialog::PopulateOrExchange ( ShuttleGui S)
private

Definition at line 95 of file AutoRecoveryDialog.cpp.

96{
97 S.SetBorder(5);
98 S.StartVerticalLay(wxEXPAND, 1);
99 {
100 S.AddFixedText(
101 XO("The following projects were not saved properly the last time Audacity was run and "
102 "can be automatically recovered.\n\n"
103 "After recovery, save the projects to ensure changes are written to disk."),
104 false,
105 500);
106
107 S.StartStatic(XO("Recoverable &projects"), 1);
108 {
110 .ConnectRoot(wxEVT_KEY_DOWN, &AutoRecoveryDialog::OnListKeyDown)
111 .AddListControlReportMode(
112 {
113 /*i18n-hint: (verb). It instruct the user to select items.*/
114 XO("Select"),
115 /*i18n-hint: (noun). It's the name of the project to recover.*/
116 XO("Name")
117 });
118 mFileList->EnableCheckBoxes();
119 PopulateList();
120 }
121 S.EndStatic();
122
123 S.StartHorizontalLay(wxALIGN_CENTRE, 0);
124 {
125 S.Id(ID_QUIT_AUDACITY).AddButton(XXO("&Quit Audacity"));
126 S.Id(ID_DISCARD_SELECTED).AddButton(XXO("&Discard Selected"));
127 S.Id(ID_RECOVER_SELECTED).AddButton(XXO("&Recover Selected"), wxALIGN_CENTRE, true);
128 S.Id(ID_SKIP).AddButton(XXO("&Skip"));
129
130 SetAffirmativeId(ID_RECOVER_SELECTED);
131 SetEscapeId(ID_SKIP);
132 }
133 S.EndHorizontalLay();
134 }
135 S.EndVerticalLay();
136
137 Layout();
138 Fit();
139 SetMinSize(GetSize());
140
141 // Sometimes it centers on wxGTK and sometimes it doesn't.
142 // Yielding before centering seems to be a good workaround,
143 // but will leave to implement on a rainy day.
144 Center();
145}
@ ID_FILE_LIST
XXO("&Cut/Copy/Paste Toolbar")
void OnListKeyDown(wxKeyEvent &evt)

References ID_DISCARD_SELECTED, ID_FILE_LIST, ID_QUIT_AUDACITY, ID_RECOVER_SELECTED, ID_SKIP, mFileList, OnListKeyDown(), PopulateList(), S, XO(), and XXO().

Here is the call graph for this function:

Member Data Documentation

◆ mFileList

wxListCtrl* AutoRecoveryDialog::mFileList
private

◆ mFiles

FilePaths AutoRecoveryDialog::mFiles
private

◆ mProject

AudacityProject* AutoRecoveryDialog::mProject
private

Definition at line 59 of file AutoRecoveryDialog.cpp.

Referenced by PopulateList().


The documentation for this class was generated from the following file: