| 1752 | } |
| 1753 | |
| 1754 | void ProjectFileIO::WriteXML(XMLWriter &xmlFile, |
| 1755 | bool recording /* = false */, |
| 1756 | const TrackList *tracks /* = nullptr */) |
| 1757 | // may throw |
| 1758 | { |
| 1759 | auto &proj = mProject; |
| 1760 | auto &tracklist = tracks ? *tracks : TrackList::Get(proj); |
| 1761 | |
| 1762 | //TIMER_START( "AudacityProject::WriteXML", xml_writer_timer ); |
| 1763 | |
| 1764 | xmlFile.StartTag(wxT("project")); |
| 1765 | xmlFile.WriteAttr(wxT("xmlns"), wxT("http://audacity.sourceforge.net/xml/")); |
| 1766 | |
| 1767 | xmlFile.WriteAttr(wxT("version"), wxT(AUDACITY_FILE_FORMAT_VERSION)); |
| 1768 | xmlFile.WriteAttr(wxT("audacityversion"), AUDACITY_VERSION_STRING); |
| 1769 | |
| 1770 | ProjectFileIORegistry::Get().CallWriters(proj, xmlFile); |
| 1771 | |
| 1772 | auto &pendingTracks = PendingTracks::Get(proj); |
| 1773 | tracklist.Any().Visit([&](const Track &t) { |
| 1774 | auto useTrack = &t; |
| 1775 | if (recording) { |
| 1776 | // When append-recording, there is a temporary "shadow" track accumulating |
| 1777 | // changes and displayed on the screen but it is not yet part of the |
| 1778 | // regular track list. That is the one that we want to back up. |
| 1779 | // SubstitutePendingChangedTrack() fetches the shadow, if the track has |
| 1780 | // one, else it gives the same track back. |
| 1781 | useTrack = &pendingTracks.SubstitutePendingChangedTrack(t); |
| 1782 | } |
| 1783 | else if (useTrack->GetId() == TrackId{}) { |
| 1784 | // This is a track added during a non-appending recording that is |
| 1785 | // not yet in the undo history. The UndoManager skips backing it up |
| 1786 | // when pushing. Don't auto-save it. |
| 1787 | return; |
| 1788 | } |
| 1789 | useTrack->WriteXML(xmlFile); |
| 1790 | }); |
| 1791 | |
| 1792 | xmlFile.EndTag(wxT("project")); |
| 1793 | |
| 1794 | //TIMER_STOP( xml_writer_timer ); |
| 1795 | } |
| 1796 | |
| 1797 | bool ProjectFileIO::AutoSave(bool recording) |
| 1798 | { |