Don't try to remove pending state file if the file doesn't exist
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <fstream>
29 #include <string>
30 #include <cerrno>
31 #include <cstdio> /* snprintf(3) ... grrr */
32 #include <cmath>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <climits>
36 #include <fcntl.h>
37 #include <poll.h>
38 #include <signal.h>
39 #include <sys/mman.h>
40 #include <sys/time.h>
41
42 #ifdef HAVE_SYS_VFS_H
43 #include <sys/vfs.h>
44 #else
45 #include <sys/param.h>
46 #include <sys/mount.h>
47 #endif
48
49 #ifdef HAVE_SYS_STATVFS_H
50 #include <sys/statvfs.h>
51 #endif
52
53 #include <glib.h>
54 #include <glib/gstdio.h>
55
56 #include <glibmm.h>
57 #include <glibmm/thread.h>
58
59 #include <boost/algorithm/string.hpp>
60
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63 #include "midi++/manager.h"
64
65 #include "evoral/SMF.hpp"
66
67 #include "pbd/boost_debug.h"
68 #include "pbd/basename.h"
69 #include "pbd/controllable_descriptor.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/filesystem.h"
73 #include "pbd/file_utils.h"
74 #include "pbd/pathscanner.h"
75 #include "pbd/pthread_utils.h"
76 #include "pbd/search_path.h"
77 #include "pbd/stacktrace.h"
78 #include "pbd/convert.h"
79 #include "pbd/clear_dir.h"
80
81 #include "ardour/amp.h"
82 #include "ardour/audio_diskstream.h"
83 #include "ardour/audio_track.h"
84 #include "ardour/audioengine.h"
85 #include "ardour/audiofilesource.h"
86 #include "ardour/audioregion.h"
87 #include "ardour/automation_control.h"
88 #include "ardour/butler.h"
89 #include "ardour/control_protocol_manager.h"
90 #include "ardour/directory_names.h"
91 #include "ardour/filename_extensions.h"
92 #include "ardour/location.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_source.h"
97 #include "ardour/midi_track.h"
98 #include "ardour/named_selection.h"
99 #include "ardour/pannable.h"
100 #include "ardour/playlist_factory.h"
101 #include "ardour/port.h"
102 #include "ardour/processor.h"
103 #include "ardour/proxy_controllable.h"
104 #include "ardour/recent_sessions.h"
105 #include "ardour/region_factory.h"
106 #include "ardour/route_group.h"
107 #include "ardour/send.h"
108 #include "ardour/session.h"
109 #include "ardour/session_directory.h"
110 #include "ardour/session_metadata.h"
111 #include "ardour/session_playlists.h"
112 #include "ardour/session_state_utils.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/sndfilesource.h"
116 #include "ardour/source_factory.h"
117 #include "ardour/speakers.h"
118 #include "ardour/template_utils.h"
119 #include "ardour/tempo.h"
120 #include "ardour/ticker.h"
121 #include "ardour/user_bundle.h"
122
123 #include "control_protocol/control_protocol.h"
124
125 #include "i18n.h"
126 #include <locale.h>
127
128 using namespace std;
129 using namespace ARDOUR;
130 using namespace PBD;
131
132 /** @param snapshot_name Snapshot name, without the .ardour prefix */
133 void
134 Session::first_stage_init (string fullpath, string snapshot_name)
135 {
136         if (fullpath.length() == 0) {
137                 destroy ();
138                 throw failed_constructor();
139         }
140
141         char buf[PATH_MAX+1];
142         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
143                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
144                 destroy ();
145                 throw failed_constructor();
146         }
147
148         _path = string(buf);
149
150         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
151                 _path += G_DIR_SEPARATOR;
152         }
153
154         /* these two are just provisional settings. set_state()
155            will likely override them.
156         */
157
158         _name = _current_snapshot_name = snapshot_name;
159
160         set_history_depth (Config->get_history_depth());
161
162         _current_frame_rate = _engine.frame_rate ();
163         _nominal_frame_rate = _current_frame_rate;
164         _base_frame_rate = _current_frame_rate;
165
166         _tempo_map = new TempoMap (_current_frame_rate);
167         _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
168
169
170         _non_soloed_outs_muted = false;
171         _listen_cnt = 0;
172         _solo_isolated_cnt = 0;
173         g_atomic_int_set (&processing_prohibited, 0);
174         _transport_speed = 0;
175         _default_transport_speed = 1.0;
176         _last_transport_speed = 0;
177         _target_transport_speed = 0;
178         auto_play_legal = false;
179         transport_sub_state = 0;
180         _transport_frame = 0;
181         _requested_return_frame = -1;
182         _session_range_location = 0;
183         g_atomic_int_set (&_record_status, Disabled);
184         loop_changing = false;
185         play_loop = false;
186         have_looped = false;
187         _last_roll_location = 0;
188         _last_roll_or_reversal_location = 0;
189         _last_record_location = 0;
190         pending_locate_frame = 0;
191         pending_locate_roll = false;
192         pending_locate_flush = false;
193         state_was_pending = false;
194         set_next_event ();
195         outbound_mtc_timecode_frame = 0;
196         next_quarter_frame_to_send = -1;
197         current_block_size = 0;
198         solo_update_disabled = false;
199         _have_captured = false;
200         _worst_output_latency = 0;
201         _worst_input_latency = 0;
202         _worst_track_latency = 0;
203         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204         _was_seamless = Config->get_seamless_loop ();
205         _slave = 0;
206         _send_qf_mtc = false;
207         _pframes_since_last_mtc = 0;
208         g_atomic_int_set (&_playback_load, 100);
209         g_atomic_int_set (&_capture_load, 100);
210         _play_range = false;
211         _exporting = false;
212         pending_abort = false;
213         destructive_index = 0;
214         first_file_data_format_reset = true;
215         first_file_header_format_reset = true;
216         post_export_sync = false;
217         midi_control_ui = 0;
218         _step_editors = 0;
219         no_questions_about_missing_files = false;
220         _speakers.reset (new Speakers);
221         _clicks_cleared = 0;
222         ignore_route_processor_changes = false;
223         _pre_export_mmc_enabled = false;
224
225         AudioDiskstream::allocate_working_buffers();
226
227         /* default short fade = 15ms */
228
229         SndFileSource::setup_standard_crossfades (*this, frame_rate());
230
231         last_mmc_step.tv_sec = 0;
232         last_mmc_step.tv_usec = 0;
233         step_speed = 0.0;
234
235         /* click sounds are unset by default, which causes us to internal
236            waveforms for clicks.
237         */
238
239         click_length = 0;
240         click_emphasis_length = 0;
241         _clicking = false;
242
243         process_function = &Session::process_with_events;
244
245         if (config.get_use_video_sync()) {
246                 waiting_for_sync_offset = true;
247         } else {
248                 waiting_for_sync_offset = false;
249         }
250
251         last_timecode_when = 0;
252         last_timecode_valid = false;
253
254         sync_time_vars ();
255
256         last_rr_session_dir = session_dirs.begin();
257         refresh_disk_space ();
258
259         /* default: assume simple stereo speaker configuration */
260
261         _speakers->setup_default_speakers (2);
262
263         /* slave stuff */
264
265         average_slave_delta = 1800; // !!! why 1800 ????
266         have_first_delta_accumulator = false;
267         delta_accumulator_cnt = 0;
268         _slave_state = Stopped;
269
270         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
271                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
272                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
273         add_controllable (_solo_cut_control);
274
275         _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
276
277         /* These are all static "per-class" signals */
278
279         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
280         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
281         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
282         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
283         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
284
285         /* stop IO objects from doing stuff until we're ready for them */
286
287         Delivery::disable_panners ();
288         IO::disable_connecting ();
289 }
290
291 int
292 Session::second_stage_init ()
293 {
294         AudioFileSource::set_peak_dir (_session_dir->peak_path());
295
296         if (!_is_new) {
297                 if (load_state (_current_snapshot_name)) {
298                         return -1;
299                 }
300         }
301
302         if (_butler->start_thread()) {
303                 return -1;
304         }
305
306         if (start_midi_thread ()) {
307                 return -1;
308         }
309
310         setup_midi_machine_control ();
311
312         // set_state() will call setup_raid_path(), but if it's a new session we need
313         // to call setup_raid_path() here.
314
315         if (state_tree) {
316                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
317                         return -1;
318                 }
319         } else {
320                 setup_raid_path(_path);
321         }
322
323         /* we can't save till after ::when_engine_running() is called,
324            because otherwise we save state with no connections made.
325            therefore, we reset _state_of_the_state because ::set_state()
326            will have cleared it.
327
328            we also have to include Loading so that any events that get
329            generated between here and the end of ::when_engine_running()
330            will be processed directly rather than queued.
331         */
332
333         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
334
335         _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
336         _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
337         setup_click_sounds (0);
338         setup_midi_control ();
339
340         /* Pay attention ... */
341
342         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
343         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
344
345         midi_clock = new MidiClockTicker ();
346         midi_clock->set_session (this);
347
348         try {
349                 when_engine_running ();
350         }
351
352         /* handle this one in a different way than all others, so that its clear what happened */
353
354         catch (AudioEngine::PortRegistrationFailure& err) {
355                 error << err.what() << endmsg;
356                 return -1;
357         }
358
359         catch (...) {
360                 return -1;
361         }
362
363         BootMessage (_("Reset Remote Controls"));
364
365         send_full_time_code (0);
366         _engine.transport_locate (0);
367
368         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
369         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
370
371         MIDI::Name::MidiPatchManager::instance().set_session (this);
372
373         /* initial program change will be delivered later; see ::config_changed() */
374
375         _state_of_the_state = Clean;
376
377         Port::set_connecting_blocked (false);
378
379         DirtyChanged (); /* EMIT SIGNAL */
380
381         if (state_was_pending) {
382                 save_state (_current_snapshot_name);
383                 remove_pending_capture_state ();
384                 state_was_pending = false;
385         }
386
387         BootMessage (_("Session loading complete"));
388
389         return 0;
390 }
391
392 string
393 Session::raid_path () const
394 {
395         SearchPath raid_search_path;
396
397         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
398                 raid_search_path += (*i).path;
399         }
400
401         return raid_search_path.to_string ();
402 }
403
404 void
405 Session::setup_raid_path (string path)
406 {
407         if (path.empty()) {
408                 return;
409         }
410
411         space_and_path sp;
412         string fspath;
413
414         session_dirs.clear ();
415
416         SearchPath search_path(path);
417         SearchPath sound_search_path;
418         SearchPath midi_search_path;
419
420         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
421                 sp.path = *i;
422                 sp.blocks = 0; // not needed
423                 session_dirs.push_back (sp);
424
425                 SessionDirectory sdir(sp.path);
426
427                 sound_search_path += sdir.sound_path ();
428                 midi_search_path += sdir.midi_path ();
429         }
430
431         // reset the round-robin soundfile path thingie
432         last_rr_session_dir = session_dirs.begin();
433 }
434
435 bool
436 Session::path_is_within_session (const std::string& path)
437 {
438         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
439                 if (PBD::path_is_within (i->path, path)) {
440                         return true;
441                 }
442         }
443         return false;
444 }
445
446 int
447 Session::ensure_subdirs ()
448 {
449         string dir;
450
451         dir = session_directory().peak_path();
452
453         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455                 return -1;
456         }
457
458         dir = session_directory().sound_path();
459
460         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462                 return -1;
463         }
464
465         dir = session_directory().midi_path();
466
467         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469                 return -1;
470         }
471
472         dir = session_directory().dead_path();
473
474         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476                 return -1;
477         }
478
479         dir = session_directory().export_path();
480
481         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483                 return -1;
484         }
485
486         dir = analysis_dir ();
487
488         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
489                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490                 return -1;
491         }
492
493         dir = plugins_dir ();
494
495         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
496                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497                 return -1;
498         }
499
500         dir = externals_dir ();
501
502         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
503                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504                 return -1;
505         }
506
507         return 0;
508 }
509
510 /** @param session_template directory containing session template, or empty.
511  *  Caller must not hold process lock.
512  */
513 int
514 Session::create (const string& session_template, BusProfile* bus_profile)
515 {
516         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
517                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
518                 return -1;
519         }
520
521         if (ensure_subdirs ()) {
522                 return -1;
523         }
524
525         _writable = exists_and_writable (_path);
526
527         if (!session_template.empty()) {
528                 std::string in_path = session_template_dir_to_file (session_template);
529
530                 ifstream in(in_path.c_str());
531
532                 if (in) {
533                         string out_path = _path;
534                         out_path += _name;
535                         out_path += statefile_suffix;
536
537                         ofstream out(out_path.c_str());
538
539                         if (out) {
540                                 out << in.rdbuf();
541                                 _is_new = false;
542
543                                 /* Copy plugin state files from template to new session */
544                                 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
545                                 copy_files (template_plugins, plugins_dir ());
546                                 
547                                 return 0;
548
549                         } else {
550                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
551                                         << endmsg;
552                                 return -1;
553                         }
554
555                 } else {
556                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
557                                 << endmsg;
558                         return -1;
559                 }
560
561         }
562
563         /* set initial start + end point */
564
565         _state_of_the_state = Clean;
566
567         /* set up Master Out and Control Out if necessary */
568
569         if (bus_profile) {
570
571                 RouteList rl;
572                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
573
574                 if (bus_profile->master_out_channels) {
575                         boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
576                         if (r->init ()) {
577                                 return -1;
578                         }
579 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
580                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
581 #endif
582                         {
583                                 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
584                                 r->input()->ensure_io (count, false, this);
585                                 r->output()->ensure_io (count, false, this);
586                         }
587
588                         rl.push_back (r);
589
590                 } else {
591                         /* prohibit auto-connect to master, because there isn't one */
592                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
593                 }
594
595                 if (!rl.empty()) {
596                         add_routes (rl, false, false, false);
597                 }
598
599                 /* this allows the user to override settings with an environment variable.
600                  */
601
602                 if (no_auto_connect()) {
603                         bus_profile->input_ac = AutoConnectOption (0);
604                         bus_profile->output_ac = AutoConnectOption (0);
605                 }
606
607                 Config->set_input_auto_connect (bus_profile->input_ac);
608                 Config->set_output_auto_connect (bus_profile->output_ac);
609         }
610
611         if (Config->get_use_monitor_bus() && bus_profile) {
612                 add_monitor_section ();
613         }
614
615         save_state ("");
616
617         return 0;
618 }
619
620 void
621 Session::maybe_write_autosave()
622 {
623         if (dirty() && record_status() != Recording) {
624                 save_state("", true);
625         }
626 }
627
628 void
629 Session::remove_pending_capture_state ()
630 {
631         std::string pending_state_file_path(_session_dir->root_path());
632
633         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
634
635         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
636
637         if (g_remove (pending_state_file_path.c_str()) != 0) {
638                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
639                                 pending_state_file_path, g_strerror (errno)) << endmsg;
640         }
641 }
642
643 /** Rename a state file.
644  *  @param old_name Old snapshot name.
645  *  @param new_name New snapshot name.
646  */
647 void
648 Session::rename_state (string old_name, string new_name)
649 {
650         if (old_name == _current_snapshot_name || old_name == _name) {
651                 /* refuse to rename the current snapshot or the "main" one */
652                 return;
653         }
654
655         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
656         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
657
658         const sys::path old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
659         const sys::path new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
660
661         try
662         {
663                 sys::rename (old_xml_path, new_xml_path);
664         }
665         catch (const sys::filesystem_error& err)
666         {
667                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
668                                 old_name, new_name, err.what()) << endmsg;
669         }
670 }
671
672 /** Remove a state file.
673  *  @param snapshot_name Snapshot name.
674  */
675 void
676 Session::remove_state (string snapshot_name)
677 {
678         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
679                 // refuse to remove the current snapshot or the "main" one
680                 return;
681         }
682
683         std::string xml_path(_session_dir->root_path());
684
685         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
686
687         if (!create_backup_file (xml_path)) {
688                 // don't remove it if a backup can't be made
689                 // create_backup_file will log the error.
690                 return;
691         }
692
693         // and delete it
694         sys::remove (xml_path);
695 }
696
697 #ifdef HAVE_JACK_SESSION
698 void
699 Session::jack_session_event (jack_session_event_t * event)
700 {
701         char timebuf[128];
702         time_t n;
703         struct tm local_time;
704
705         time (&n);
706         localtime_r (&n, &local_time);
707         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
708
709         if (event->type == JackSessionSaveTemplate)
710         {
711                 if (save_template( timebuf )) {
712                         event->flags = JackSessionSaveError;
713                 } else {
714                         string cmd ("ardour3 -P -U ");
715                         cmd += event->client_uuid;
716                         cmd += " -T ";
717                         cmd += timebuf;
718
719                         event->command_line = strdup (cmd.c_str());
720                 }
721         }
722         else
723         {
724                 if (save_state (timebuf)) {
725                         event->flags = JackSessionSaveError;
726                 } else {
727                         sys::path xml_path (_session_dir->root_path());
728                         xml_path /= legalize_for_path (timebuf) + statefile_suffix;
729
730                         string cmd ("ardour3 -P -U ");
731                         cmd += event->client_uuid;
732                         cmd += " \"";
733                         cmd += xml_path.to_string();
734                         cmd += '\"';
735
736                         event->command_line = strdup (cmd.c_str());
737                 }
738         }
739
740         jack_session_reply (_engine.jack(), event);
741
742         if (event->type == JackSessionSaveAndQuit) {
743                 Quit (); /* EMIT SIGNAL */
744         }
745
746         jack_session_event_free( event );
747 }
748 #endif
749
750 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
751 int
752 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
753 {
754         XMLTree tree;
755         std::string xml_path(_session_dir->root_path());
756
757         if (!_writable || (_state_of_the_state & CannotSave)) {
758                 return 1;
759         }
760
761         if (!_engine.connected ()) {
762                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
763                                          PROGRAM_NAME)
764                       << endmsg;
765                 return 1;
766         }
767
768         /* tell sources we're saving first, in case they write out to a new file
769          * which should be saved with the state rather than the old one */
770         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
771                 try {
772                         i->second->session_saved();
773                 } catch (Evoral::SMF::FileError& e) {
774                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
775                 }
776         }
777
778         tree.set_root (&get_state());
779
780         if (snapshot_name.empty()) {
781                 snapshot_name = _current_snapshot_name;
782         } else if (switch_to_snapshot) {
783                 _current_snapshot_name = snapshot_name;
784         }
785
786         if (!pending) {
787
788                 /* proper save: use statefile_suffix (.ardour in English) */
789
790                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
791
792                 /* make a backup copy of the old file */
793
794                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
795                         // create_backup_file will log the error
796                         return -1;
797                 }
798
799         } else {
800
801                 /* pending save: use pending_suffix (.pending in English) */
802                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
803         }
804
805         sys::path tmp_path(_session_dir->root_path());
806
807         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
808
809         // cerr << "actually writing state to " << xml_path.to_string() << endl;
810
811         if (!tree.write (tmp_path.to_string())) {
812                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
813                 sys::remove (tmp_path);
814                 return -1;
815
816         } else {
817
818                 if (::rename (tmp_path.to_string().c_str(), xml_path.c_str()) != 0) {
819                         error << string_compose (_("could not rename temporary session file %1 to %2"),
820                                         tmp_path.to_string(), xml_path) << endmsg;
821                         sys::remove (tmp_path);
822                         return -1;
823                 }
824         }
825
826         if (!pending) {
827
828                 save_history (snapshot_name);
829
830                 bool was_dirty = dirty();
831
832                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
833
834                 if (was_dirty) {
835                         DirtyChanged (); /* EMIT SIGNAL */
836                 }
837
838                 StateSaved (snapshot_name); /* EMIT SIGNAL */
839         }
840
841         return 0;
842 }
843
844 int
845 Session::restore_state (string snapshot_name)
846 {
847         if (load_state (snapshot_name) == 0) {
848                 set_state (*state_tree->root(), Stateful::loading_state_version);
849         }
850
851         return 0;
852 }
853
854 int
855 Session::load_state (string snapshot_name)
856 {
857         delete state_tree;
858         state_tree = 0;
859
860         state_was_pending = false;
861
862         /* check for leftover pending state from a crashed capture attempt */
863
864         sys::path xmlpath(_session_dir->root_path());
865         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
866
867         if (sys::exists (xmlpath)) {
868
869                 /* there is pending state from a crashed capture attempt */
870
871                 boost::optional<int> r = AskAboutPendingState();
872                 if (r.get_value_or (1)) {
873                         state_was_pending = true;
874                 }
875         }
876
877         if (!state_was_pending) {
878                 xmlpath = _session_dir->root_path();
879                 xmlpath /= snapshot_name;
880         }
881
882         if (!sys::exists (xmlpath)) {
883                 xmlpath = _session_dir->root_path();
884                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
885                 if (!sys::exists (xmlpath)) {
886                         error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
887                         return 1;
888                 }
889         }
890
891         state_tree = new XMLTree;
892
893         set_dirty();
894
895         _writable = exists_and_writable (xmlpath.to_string());
896
897         if (!state_tree->read (xmlpath.to_string())) {
898                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
899                 delete state_tree;
900                 state_tree = 0;
901                 return -1;
902         }
903
904         XMLNode& root (*state_tree->root());
905
906         if (root.name() != X_("Session")) {
907                 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
908                 delete state_tree;
909                 state_tree = 0;
910                 return -1;
911         }
912
913         const XMLProperty* prop;
914
915         if ((prop = root.property ("version")) == 0) {
916                 /* no version implies very old version of Ardour */
917                 Stateful::loading_state_version = 1000;
918         } else {
919                 if (prop->value().find ('.') != string::npos) {
920                         /* old school version format */
921                         if (prop->value()[0] == '2') {
922                                 Stateful::loading_state_version = 2000;
923                         } else {
924                                 Stateful::loading_state_version = 3000;
925                         }
926                 } else {
927                         Stateful::loading_state_version = atoi (prop->value());
928                 }
929         }
930
931         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
932
933                 sys::path backup_path(_session_dir->root_path());
934
935                 backup_path /= string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
936
937                 // only create a backup for a given statefile version once
938
939                 if (!sys::exists (backup_path)) {
940                         
941                         info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
942                                                 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
943                              << endmsg;
944                         
945                         if (!copy_file (xmlpath.to_string(), backup_path.to_string())) {;
946                                 return -1;
947                         }
948                 }
949         }
950
951         return 0;
952 }
953
954 int
955 Session::load_options (const XMLNode& node)
956 {
957         LocaleGuard lg (X_("POSIX"));
958         config.set_variables (node);
959         return 0;
960 }
961
962 XMLNode&
963 Session::get_state()
964 {
965         return state(true);
966 }
967
968 XMLNode&
969 Session::get_template()
970 {
971         /* if we don't disable rec-enable, diskstreams
972            will believe they need to store their capture
973            sources in their state node.
974         */
975
976         disable_record (false);
977
978         return state(false);
979 }
980
981 XMLNode&
982 Session::state (bool full_state)
983 {
984         XMLNode* node = new XMLNode("Session");
985         XMLNode* child;
986
987         char buf[16];
988         snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
989         node->add_property("version", buf);
990
991         /* store configuration settings */
992
993         if (full_state) {
994
995                 node->add_property ("name", _name);
996                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
997                 node->add_property ("sample-rate", buf);
998
999                 if (session_dirs.size() > 1) {
1000
1001                         string p;
1002
1003                         vector<space_and_path>::iterator i = session_dirs.begin();
1004                         vector<space_and_path>::iterator next;
1005
1006                         ++i; /* skip the first one */
1007                         next = i;
1008                         ++next;
1009
1010                         while (i != session_dirs.end()) {
1011
1012                                 p += (*i).path;
1013
1014                                 if (next != session_dirs.end()) {
1015                                         p += ':';
1016                                 } else {
1017                                         break;
1018                                 }
1019
1020                                 ++next;
1021                                 ++i;
1022                         }
1023
1024                         child = node->add_child ("Path");
1025                         child->add_content (p);
1026                 }
1027         }
1028
1029         /* save the ID counter */
1030
1031         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1032         node->add_property ("id-counter", buf);
1033
1034         /* save the event ID counter */
1035
1036         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1037         node->add_property ("event-counter", buf);
1038
1039         /* various options */
1040
1041         node->add_child_nocopy (config.get_variables ());
1042
1043         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1044
1045         child = node->add_child ("Sources");
1046
1047         if (full_state) {
1048                 Glib::Mutex::Lock sl (source_lock);
1049
1050                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1051
1052                         /* Don't save information about non-file Sources, or
1053                          * about non-destructive file sources that are empty
1054                          * and unused by any regions.
1055                         */
1056
1057                         boost::shared_ptr<FileSource> fs;
1058
1059                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1060
1061                                 if (!fs->destructive()) {
1062                                         if (fs->empty() && !fs->used()) {
1063                                                 continue;
1064                                         }
1065                                 }
1066
1067                                 child->add_child_nocopy (siter->second->get_state());
1068                         }
1069                 }
1070         }
1071
1072         child = node->add_child ("Regions");
1073
1074         if (full_state) {
1075                 Glib::Mutex::Lock rl (region_lock);
1076                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1077                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1078                         boost::shared_ptr<Region> r = i->second;
1079                         /* only store regions not attached to playlists */
1080                         if (r->playlist() == 0) {
1081                                 child->add_child_nocopy (r->state ());
1082                         }
1083                 }
1084
1085                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1086
1087                 if (!cassocs.empty()) {
1088                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1089
1090                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1091                                 char buf[64];
1092                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1093                                 i->first->id().print (buf, sizeof (buf));
1094                                 can->add_property (X_("copy"), buf);
1095                                 i->second->id().print (buf, sizeof (buf));
1096                                 can->add_property (X_("original"), buf);
1097                                 ca->add_child_nocopy (*can);
1098                         }
1099                 }
1100         }
1101
1102         if (full_state) {
1103                 node->add_child_nocopy (_locations->get_state());
1104         } else {
1105                 // for a template, just create a new Locations, populate it
1106                 // with the default start and end, and get the state for that.
1107                 Locations loc (*this);
1108                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1109                 range->set (max_framepos, 0);
1110                 loc.add (range);
1111                 node->add_child_nocopy (loc.get_state());
1112         }
1113
1114         child = node->add_child ("Bundles");
1115         {
1116                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1117                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1118                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1119                         if (b) {
1120                                 child->add_child_nocopy (b->get_state());
1121                         }
1122                 }
1123         }
1124
1125         child = node->add_child ("Routes");
1126         {
1127                 boost::shared_ptr<RouteList> r = routes.reader ();
1128
1129                 RoutePublicOrderSorter cmp;
1130                 RouteList public_order (*r);
1131                 public_order.sort (cmp);
1132
1133                 /* the sort should have put control outs first */
1134
1135                 if (_monitor_out) {
1136                         assert (_monitor_out == public_order.front());
1137                 }
1138
1139                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1140                         if (!(*i)->is_hidden()) {
1141                                 if (full_state) {
1142                                         child->add_child_nocopy ((*i)->get_state());
1143                                 } else {
1144                                         child->add_child_nocopy ((*i)->get_template());
1145                                 }
1146                         }
1147                 }
1148         }
1149
1150         playlists->add_state (node, full_state);
1151
1152         child = node->add_child ("RouteGroups");
1153         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1154                 child->add_child_nocopy ((*i)->get_state());
1155         }
1156
1157         if (_click_io) {
1158                 XMLNode* gain_child = node->add_child ("Click");
1159                 gain_child->add_child_nocopy (_click_io->state (full_state));
1160                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1161         }
1162
1163         if (full_state) {
1164                 XMLNode* ns_child = node->add_child ("NamedSelections");
1165                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1166                         if (full_state) {
1167                                 ns_child->add_child_nocopy ((*i)->get_state());
1168                         }
1169                 }
1170         }
1171
1172         node->add_child_nocopy (_speakers->get_state());
1173         node->add_child_nocopy (_tempo_map->get_state());
1174         node->add_child_nocopy (get_control_protocol_state());
1175
1176         if (_extra_xml) {
1177                 node->add_child_copy (*_extra_xml);
1178         }
1179
1180         return *node;
1181 }
1182
1183 XMLNode&
1184 Session::get_control_protocol_state ()
1185 {
1186         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1187         return cpm.get_state();
1188 }
1189
1190 int
1191 Session::set_state (const XMLNode& node, int version)
1192 {
1193         XMLNodeList nlist;
1194         XMLNode* child;
1195         const XMLProperty* prop;
1196         int ret = -1;
1197
1198         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1199
1200         if (node.name() != X_("Session")) {
1201                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1202                 return -1;
1203         }
1204
1205         if ((prop = node.property ("name")) != 0) {
1206                 _name = prop->value ();
1207         }
1208
1209         if ((prop = node.property (X_("sample-rate"))) != 0) {
1210
1211                 _nominal_frame_rate = atoi (prop->value());
1212
1213                 if (_nominal_frame_rate != _current_frame_rate) {
1214                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1215                         if (r.get_value_or (0)) {
1216                                 return -1;
1217                         }
1218                 }
1219         }
1220
1221         setup_raid_path(_session_dir->root_path());
1222
1223         if ((prop = node.property (X_("id-counter"))) != 0) {
1224                 uint64_t x;
1225                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1226                 ID::init_counter (x);
1227         } else {
1228                 /* old sessions used a timebased counter, so fake
1229                    the startup ID counter based on a standard
1230                    timestamp.
1231                 */
1232                 time_t now;
1233                 time (&now);
1234                 ID::init_counter (now);
1235         }
1236
1237         if ((prop = node.property (X_("event-counter"))) != 0) {
1238                 Evoral::init_event_id_counter (atoi (prop->value()));
1239         }
1240
1241         IO::disable_connecting ();
1242
1243         Stateful::save_extra_xml (node);
1244
1245         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1246                 load_options (*child);
1247         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1248                 load_options (*child);
1249         } else {
1250                 error << _("Session: XML state has no options section") << endmsg;
1251         }
1252
1253         if (version >= 3000) {
1254                 if ((child = find_named_node (node, "Metadata")) == 0) {
1255                         warning << _("Session: XML state has no metadata section") << endmsg;
1256                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1257                         goto out;
1258                 }
1259         }
1260
1261         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1262                 _speakers->set_state (*child, version);
1263         }
1264
1265         if ((child = find_named_node (node, "Sources")) == 0) {
1266                 error << _("Session: XML state has no sources section") << endmsg;
1267                 goto out;
1268         } else if (load_sources (*child)) {
1269                 goto out;
1270         }
1271
1272         if ((child = find_named_node (node, "TempoMap")) == 0) {
1273                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1274                 goto out;
1275         } else if (_tempo_map->set_state (*child, version)) {
1276                 goto out;
1277         }
1278
1279         if ((child = find_named_node (node, "Locations")) == 0) {
1280                 error << _("Session: XML state has no locations section") << endmsg;
1281                 goto out;
1282         } else if (_locations->set_state (*child, version)) {
1283                 goto out;
1284         }
1285
1286         Location* location;
1287
1288         if ((location = _locations->auto_loop_location()) != 0) {
1289                 set_auto_loop_location (location);
1290         }
1291
1292         if ((location = _locations->auto_punch_location()) != 0) {
1293                 set_auto_punch_location (location);
1294         }
1295
1296         if ((location = _locations->session_range_location()) != 0) {
1297                 delete _session_range_location;
1298                 _session_range_location = location;
1299         }
1300
1301         if (_session_range_location) {
1302                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1303         }
1304
1305         if ((child = find_named_node (node, "Regions")) == 0) {
1306                 error << _("Session: XML state has no Regions section") << endmsg;
1307                 goto out;
1308         } else if (load_regions (*child)) {
1309                 goto out;
1310         }
1311
1312         if ((child = find_named_node (node, "Playlists")) == 0) {
1313                 error << _("Session: XML state has no playlists section") << endmsg;
1314                 goto out;
1315         } else if (playlists->load (*this, *child)) {
1316                 goto out;
1317         }
1318
1319         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1320                 // this is OK
1321         } else if (playlists->load_unused (*this, *child)) {
1322                 goto out;
1323         }
1324
1325         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1326                 if (load_compounds (*child)) {
1327                         goto out;
1328                 }
1329         }
1330
1331         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1332                 if (load_named_selections (*child)) {
1333                         goto out;
1334                 }
1335         }
1336
1337         if (version >= 3000) {
1338                 if ((child = find_named_node (node, "Bundles")) == 0) {
1339                         warning << _("Session: XML state has no bundles section") << endmsg;
1340                         //goto out;
1341                 } else {
1342                         /* We can't load Bundles yet as they need to be able
1343                            to convert from port names to Port objects, which can't happen until
1344                            later */
1345                         _bundle_xml_node = new XMLNode (*child);
1346                 }
1347         }
1348
1349         if (version < 3000) {
1350                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1351                         error << _("Session: XML state has no diskstreams section") << endmsg;
1352                         goto out;
1353                 } else if (load_diskstreams_2X (*child, version)) {
1354                         goto out;
1355                 }
1356         }
1357
1358         if ((child = find_named_node (node, "Routes")) == 0) {
1359                 error << _("Session: XML state has no routes section") << endmsg;
1360                 goto out;
1361         } else if (load_routes (*child, version)) {
1362                 goto out;
1363         }
1364
1365         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1366         _diskstreams_2X.clear ();
1367
1368         if (version >= 3000) {
1369
1370                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1371                         error << _("Session: XML state has no route groups section") << endmsg;
1372                         goto out;
1373                 } else if (load_route_groups (*child, version)) {
1374                         goto out;
1375                 }
1376
1377         } else if (version < 3000) {
1378
1379                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1380                         error << _("Session: XML state has no edit groups section") << endmsg;
1381                         goto out;
1382                 } else if (load_route_groups (*child, version)) {
1383                         goto out;
1384                 }
1385
1386                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1387                         error << _("Session: XML state has no mix groups section") << endmsg;
1388                         goto out;
1389                 } else if (load_route_groups (*child, version)) {
1390                         goto out;
1391                 }
1392         }
1393
1394         if ((child = find_named_node (node, "Click")) == 0) {
1395                 warning << _("Session: XML state has no click section") << endmsg;
1396         } else if (_click_io) {
1397                 const XMLNodeList& children (child->children());
1398                 XMLNodeList::const_iterator i = children.begin();
1399                 _click_io->set_state (**i, version);
1400                 ++i;
1401                 if (i != children.end()) {
1402                         _click_gain->set_state (**i, version);
1403                 }
1404         }
1405
1406         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1407                 ControlProtocolManager::instance().set_protocol_states (*child);
1408         }
1409
1410         update_have_rec_enabled_track ();
1411
1412         /* here beginneth the second phase ... */
1413
1414         StateReady (); /* EMIT SIGNAL */
1415
1416         return 0;
1417
1418   out:
1419         return ret;
1420 }
1421
1422 int
1423 Session::load_routes (const XMLNode& node, int version)
1424 {
1425         XMLNodeList nlist;
1426         XMLNodeConstIterator niter;
1427         RouteList new_routes;
1428
1429         nlist = node.children();
1430
1431         set_dirty();
1432
1433         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1434
1435                 boost::shared_ptr<Route> route;
1436                 if (version < 3000) {
1437                         route = XMLRouteFactory_2X (**niter, version);
1438                 } else {
1439                         route = XMLRouteFactory (**niter, version);
1440                 }
1441
1442                 if (route == 0) {
1443                         error << _("Session: cannot create Route from XML description.") << endmsg;
1444                         return -1;
1445                 }
1446
1447                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1448
1449                 new_routes.push_back (route);
1450         }
1451
1452         add_routes (new_routes, false, false, false);
1453
1454         return 0;
1455 }
1456
1457 boost::shared_ptr<Route>
1458 Session::XMLRouteFactory (const XMLNode& node, int version)
1459 {
1460         boost::shared_ptr<Route> ret;
1461
1462         if (node.name() != "Route") {
1463                 return ret;
1464         }
1465
1466         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1467
1468         DataType type = DataType::AUDIO;
1469         const XMLProperty* prop = node.property("default-type");
1470
1471         if (prop) {
1472                 type = DataType (prop->value());
1473         }
1474
1475         assert (type != DataType::NIL);
1476
1477         if (ds_child) {
1478
1479                 boost::shared_ptr<Track> track;
1480
1481                 if (type == DataType::AUDIO) {
1482                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1483                 } else {
1484                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1485                 }
1486
1487                 if (track->init()) {
1488                         return ret;
1489                 }
1490
1491                 if (track->set_state (node, version)) {
1492                         return ret;
1493                 }
1494
1495 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1496                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1497 #endif
1498                 ret = track;
1499
1500         } else {
1501                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1502
1503                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1504 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1505                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1506 #endif
1507                         ret = r;
1508                 }
1509         }
1510
1511         return ret;
1512 }
1513
1514 boost::shared_ptr<Route>
1515 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1516 {
1517         boost::shared_ptr<Route> ret;
1518
1519         if (node.name() != "Route") {
1520                 return ret;
1521         }
1522
1523         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1524         if (!ds_prop) {
1525                 ds_prop = node.property (X_("diskstream"));
1526         }
1527
1528         DataType type = DataType::AUDIO;
1529         const XMLProperty* prop = node.property("default-type");
1530
1531         if (prop) {
1532                 type = DataType (prop->value());
1533         }
1534
1535         assert (type != DataType::NIL);
1536
1537         if (ds_prop) {
1538
1539                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1540                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1541                         ++i;
1542                 }
1543
1544                 if (i == _diskstreams_2X.end()) {
1545                         error << _("Could not find diskstream for route") << endmsg;
1546                         return boost::shared_ptr<Route> ();
1547                 }
1548
1549                 boost::shared_ptr<Track> track;
1550
1551                 if (type == DataType::AUDIO) {
1552                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1553                 } else {
1554                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1555                 }
1556
1557                 if (track->init()) {
1558                         return ret;
1559                 }
1560
1561                 if (track->set_state (node, version)) {
1562                         return ret;
1563                 }
1564
1565                 track->set_diskstream (*i);
1566
1567 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1568                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1569 #endif
1570                 ret = track;
1571
1572         } else {
1573                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1574
1575                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1576 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1577                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1578 #endif
1579                         ret = r;
1580                 }
1581         }
1582
1583         return ret;
1584 }
1585
1586 int
1587 Session::load_regions (const XMLNode& node)
1588 {
1589         XMLNodeList nlist;
1590         XMLNodeConstIterator niter;
1591         boost::shared_ptr<Region> region;
1592
1593         nlist = node.children();
1594
1595         set_dirty();
1596
1597         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1598                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1599                         error << _("Session: cannot create Region from XML description.");
1600                         const XMLProperty *name = (**niter).property("name");
1601
1602                         if (name) {
1603                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1604                         }
1605
1606                         error << endmsg;
1607                 }
1608         }
1609
1610         return 0;
1611 }
1612
1613 int
1614 Session::load_compounds (const XMLNode& node)
1615 {
1616         XMLNodeList calist = node.children();
1617         XMLNodeConstIterator caiter;
1618         XMLProperty *caprop;
1619
1620         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1621                 XMLNode* ca = *caiter;
1622                 ID orig_id;
1623                 ID copy_id;
1624
1625                 if ((caprop = ca->property (X_("original"))) == 0) {
1626                         continue;
1627                 }
1628                 orig_id = caprop->value();
1629
1630                 if ((caprop = ca->property (X_("copy"))) == 0) {
1631                         continue;
1632                 }
1633                 copy_id = caprop->value();
1634
1635                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1636                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1637
1638                 if (!orig || !copy) {
1639                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1640                                                    orig_id, copy_id)
1641                                 << endmsg;
1642                         continue;
1643                 }
1644
1645                 RegionFactory::add_compound_association (orig, copy);
1646         }
1647
1648         return 0;
1649 }
1650
1651 void
1652 Session::load_nested_sources (const XMLNode& node)
1653 {
1654         XMLNodeList nlist;
1655         XMLNodeConstIterator niter;
1656
1657         nlist = node.children();
1658
1659         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1660                 if ((*niter)->name() == "Source") {
1661
1662                         /* it may already exist, so don't recreate it unnecessarily 
1663                          */
1664
1665                         XMLProperty* prop = (*niter)->property (X_("id"));
1666                         if (!prop) {
1667                                 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1668                                 continue;
1669                         }
1670
1671                         ID source_id (prop->value());
1672
1673                         if (!source_by_id (source_id)) {
1674
1675                                 try {
1676                                         SourceFactory::create (*this, **niter, true);
1677                                 }
1678                                 catch (failed_constructor& err) {
1679                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1680                                 }
1681                         }
1682                 }
1683         }
1684 }
1685
1686 boost::shared_ptr<Region>
1687 Session::XMLRegionFactory (const XMLNode& node, bool full)
1688 {
1689         const XMLProperty* type = node.property("type");
1690
1691         try {
1692
1693                 const XMLNodeList& nlist = node.children();
1694
1695                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1696                         XMLNode *child = (*niter);
1697                         if (child->name() == "NestedSource") {
1698                                 load_nested_sources (*child);
1699                         }
1700                 }
1701
1702                 if (!type || type->value() == "audio") {
1703                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1704                 } else if (type->value() == "midi") {
1705                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1706                 }
1707
1708         } catch (failed_constructor& err) {
1709                 return boost::shared_ptr<Region> ();
1710         }
1711
1712         return boost::shared_ptr<Region> ();
1713 }
1714
1715 boost::shared_ptr<AudioRegion>
1716 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1717 {
1718         const XMLProperty* prop;
1719         boost::shared_ptr<Source> source;
1720         boost::shared_ptr<AudioSource> as;
1721         SourceList sources;
1722         SourceList master_sources;
1723         uint32_t nchans = 1;
1724         char buf[128];
1725
1726         if (node.name() != X_("Region")) {
1727                 return boost::shared_ptr<AudioRegion>();
1728         }
1729
1730         if ((prop = node.property (X_("channels"))) != 0) {
1731                 nchans = atoi (prop->value().c_str());
1732         }
1733
1734         if ((prop = node.property ("name")) == 0) {
1735                 cerr << "no name for this region\n";
1736                 abort ();
1737         }
1738
1739         if ((prop = node.property (X_("source-0"))) == 0) {
1740                 if ((prop = node.property ("source")) == 0) {
1741                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1742                         return boost::shared_ptr<AudioRegion>();
1743                 }
1744         }
1745
1746         PBD::ID s_id (prop->value());
1747
1748         if ((source = source_by_id (s_id)) == 0) {
1749                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1750                 return boost::shared_ptr<AudioRegion>();
1751         }
1752
1753         as = boost::dynamic_pointer_cast<AudioSource>(source);
1754         if (!as) {
1755                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1756                 return boost::shared_ptr<AudioRegion>();
1757         }
1758
1759         sources.push_back (as);
1760
1761         /* pickup other channels */
1762
1763         for (uint32_t n=1; n < nchans; ++n) {
1764                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1765                 if ((prop = node.property (buf)) != 0) {
1766
1767                         PBD::ID id2 (prop->value());
1768
1769                         if ((source = source_by_id (id2)) == 0) {
1770                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1771                                 return boost::shared_ptr<AudioRegion>();
1772                         }
1773
1774                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1775                         if (!as) {
1776                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1777                                 return boost::shared_ptr<AudioRegion>();
1778                         }
1779                         sources.push_back (as);
1780                 }
1781         }
1782
1783         for (uint32_t n = 0; n < nchans; ++n) {
1784                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1785                 if ((prop = node.property (buf)) != 0) {
1786
1787                         PBD::ID id2 (prop->value());
1788
1789                         if ((source = source_by_id (id2)) == 0) {
1790                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1791                                 return boost::shared_ptr<AudioRegion>();
1792                         }
1793
1794                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1795                         if (!as) {
1796                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1797                                 return boost::shared_ptr<AudioRegion>();
1798                         }
1799                         master_sources.push_back (as);
1800                 }
1801         }
1802
1803         try {
1804                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1805
1806                 /* a final detail: this is the one and only place that we know how long missing files are */
1807
1808                 if (region->whole_file()) {
1809                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1810                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1811                                 if (sfp) {
1812                                         sfp->set_length (region->length());
1813                                 }
1814                         }
1815                 }
1816
1817                 if (!master_sources.empty()) {
1818                         if (master_sources.size() != nchans) {
1819                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1820                         } else {
1821                                 region->set_master_sources (master_sources);
1822                         }
1823                 }
1824
1825                 return region;
1826
1827         }
1828
1829         catch (failed_constructor& err) {
1830                 return boost::shared_ptr<AudioRegion>();
1831         }
1832 }
1833
1834 boost::shared_ptr<MidiRegion>
1835 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1836 {
1837         const XMLProperty* prop;
1838         boost::shared_ptr<Source> source;
1839         boost::shared_ptr<MidiSource> ms;
1840         SourceList sources;
1841
1842         if (node.name() != X_("Region")) {
1843                 return boost::shared_ptr<MidiRegion>();
1844         }
1845
1846         if ((prop = node.property ("name")) == 0) {
1847                 cerr << "no name for this region\n";
1848                 abort ();
1849         }
1850
1851         if ((prop = node.property (X_("source-0"))) == 0) {
1852                 if ((prop = node.property ("source")) == 0) {
1853                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1854                         return boost::shared_ptr<MidiRegion>();
1855                 }
1856         }
1857
1858         PBD::ID s_id (prop->value());
1859
1860         if ((source = source_by_id (s_id)) == 0) {
1861                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1862                 return boost::shared_ptr<MidiRegion>();
1863         }
1864
1865         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1866         if (!ms) {
1867                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1868                 return boost::shared_ptr<MidiRegion>();
1869         }
1870
1871         sources.push_back (ms);
1872
1873         try {
1874                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1875                 /* a final detail: this is the one and only place that we know how long missing files are */
1876
1877                 if (region->whole_file()) {
1878                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1879                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1880                                 if (sfp) {
1881                                         sfp->set_length (region->length());
1882                                 }
1883                         }
1884                 }
1885
1886                 return region;
1887         }
1888
1889         catch (failed_constructor& err) {
1890                 return boost::shared_ptr<MidiRegion>();
1891         }
1892 }
1893
1894 XMLNode&
1895 Session::get_sources_as_xml ()
1896
1897 {
1898         XMLNode* node = new XMLNode (X_("Sources"));
1899         Glib::Mutex::Lock lm (source_lock);
1900
1901         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1902                 node->add_child_nocopy (i->second->get_state());
1903         }
1904
1905         return *node;
1906 }
1907
1908 string
1909 Session::path_from_region_name (DataType type, string name, string identifier)
1910 {
1911         char buf[PATH_MAX+1];
1912         uint32_t n;
1913         SessionDirectory sdir(get_best_session_directory_for_new_source());
1914         sys::path source_dir = ((type == DataType::AUDIO)
1915                 ? sdir.sound_path() : sdir.midi_path());
1916
1917         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1918
1919         for (n = 0; n < 999999; ++n) {
1920                 if (identifier.length()) {
1921                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1922                                   identifier.c_str(), n, ext.c_str());
1923                 } else {
1924                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1925                                         n, ext.c_str());
1926                 }
1927
1928                 sys::path source_path = source_dir / buf;
1929
1930                 if (!sys::exists (source_path)) {
1931                         return source_path.to_string();
1932                 }
1933         }
1934
1935         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1936                                  name, identifier)
1937               << endmsg;
1938
1939         return "";
1940 }
1941
1942
1943 int
1944 Session::load_sources (const XMLNode& node)
1945 {
1946         XMLNodeList nlist;
1947         XMLNodeConstIterator niter;
1948         boost::shared_ptr<Source> source;
1949
1950         nlist = node.children();
1951
1952         set_dirty();
1953
1954         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1955           retry:
1956                 try {
1957                         if ((source = XMLSourceFactory (**niter)) == 0) {
1958                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1959                         }
1960
1961                 } catch (MissingSource& err) {
1962
1963                         int user_choice;
1964
1965                         if (!no_questions_about_missing_files) {
1966                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1967                         } else {
1968                                 user_choice = -2;
1969                         }
1970
1971                         switch (user_choice) {
1972                         case 0:
1973                                 /* user added a new search location, so try again */
1974                                 goto retry;
1975
1976
1977                         case 1:
1978                                 /* user asked to quit the entire session load
1979                                  */
1980                                 return -1;
1981
1982                         case 2:
1983                                 no_questions_about_missing_files = true;
1984                                 goto retry;
1985
1986                         case 3:
1987                                 no_questions_about_missing_files = true;
1988                                 /* fallthru */
1989
1990                         case -1:
1991                         default:
1992                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1993                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1994                                 break;
1995                         }
1996                 }
1997         }
1998
1999         return 0;
2000 }
2001
2002 boost::shared_ptr<Source>
2003 Session::XMLSourceFactory (const XMLNode& node)
2004 {
2005         if (node.name() != "Source") {
2006                 return boost::shared_ptr<Source>();
2007         }
2008
2009         try {
2010                 /* note: do peak building in another thread when loading session state */
2011                 return SourceFactory::create (*this, node, true);
2012         }
2013
2014         catch (failed_constructor& err) {
2015                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2016                 return boost::shared_ptr<Source>();
2017         }
2018 }
2019
2020 int
2021 Session::save_template (string template_name)
2022 {
2023         XMLTree tree;
2024
2025         if (_state_of_the_state & CannotSave) {
2026                 return -1;
2027         }
2028
2029         sys::path user_template_dir(user_template_directory());
2030
2031         try
2032         {
2033                 sys::create_directories (user_template_dir);
2034         }
2035         catch(sys::filesystem_error& ex)
2036         {
2037                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2038                                 user_template_dir.to_string(), ex.what()) << endmsg;
2039                 return -1;
2040         }
2041
2042         tree.set_root (&get_template());
2043
2044         sys::path template_dir_path(user_template_dir);
2045         
2046         /* directory to put the template in */
2047         template_dir_path /= template_name;
2048         if (sys::exists (template_dir_path))
2049         {
2050                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2051                                 template_dir_path.to_string()) << endmsg;
2052                 return -1;
2053         }
2054         
2055         sys::create_directories (template_dir_path);
2056
2057         /* file to write */
2058         sys::path template_file_path = template_dir_path;
2059         template_file_path /= template_name + template_suffix;
2060
2061         if (!tree.write (template_file_path.to_string())) {
2062                 error << _("template not saved") << endmsg;
2063                 return -1;
2064         }
2065
2066         /* copy plugin state directory */
2067
2068         sys::path template_plugin_state_path = template_dir_path;
2069         template_plugin_state_path /= X_("plugins");
2070         sys::create_directories (template_plugin_state_path);
2071         copy_files (plugins_dir(), template_plugin_state_path.to_string());
2072
2073         return 0;
2074 }
2075
2076 void
2077 Session::refresh_disk_space ()
2078 {
2079 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2080         
2081         Glib::Mutex::Lock lm (space_lock);
2082
2083         /* get freespace on every FS that is part of the session path */
2084
2085         _total_free_4k_blocks = 0;
2086         _total_free_4k_blocks_uncertain = false;
2087
2088         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2089
2090                 struct statfs statfsbuf;
2091                 statfs (i->path.c_str(), &statfsbuf);
2092
2093                 double const scale = statfsbuf.f_bsize / 4096.0;
2094
2095                 /* See if this filesystem is read-only */
2096                 struct statvfs statvfsbuf;
2097                 statvfs (i->path.c_str(), &statvfsbuf);
2098
2099                 /* f_bavail can be 0 if it is undefined for whatever
2100                    filesystem we are looking at; Samba shares mounted
2101                    via GVFS are an example of this.
2102                 */
2103                 if (statfsbuf.f_bavail == 0) {
2104                         /* block count unknown */
2105                         i->blocks = 0;
2106                         i->blocks_unknown = true;
2107                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2108                         /* read-only filesystem */
2109                         i->blocks = 0;
2110                         i->blocks_unknown = false;
2111                 } else {
2112                         /* read/write filesystem with known space */
2113                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2114                         i->blocks_unknown = false;
2115                 }
2116
2117                 _total_free_4k_blocks += i->blocks;
2118                 if (i->blocks_unknown) {
2119                         _total_free_4k_blocks_uncertain = true;
2120                 }
2121         }
2122 #endif
2123 }
2124
2125 string
2126 Session::get_best_session_directory_for_new_source ()
2127 {
2128         vector<space_and_path>::iterator i;
2129         string result = _session_dir->root_path();
2130
2131         /* handle common case without system calls */
2132
2133         if (session_dirs.size() == 1) {
2134                 return result;
2135         }
2136
2137         /* OK, here's the algorithm we're following here:
2138
2139         We want to select which directory to use for
2140         the next file source to be created. Ideally,
2141         we'd like to use a round-robin process so as to
2142         get maximum performance benefits from splitting
2143         the files across multiple disks.
2144
2145         However, in situations without much diskspace, an
2146         RR approach may end up filling up a filesystem
2147         with new files while others still have space.
2148         Its therefore important to pay some attention to
2149         the freespace in the filesystem holding each
2150         directory as well. However, if we did that by
2151         itself, we'd keep creating new files in the file
2152         system with the most space until it was as full
2153         as all others, thus negating any performance
2154         benefits of this RAID-1 like approach.
2155
2156         So, we use a user-configurable space threshold. If
2157         there are at least 2 filesystems with more than this
2158         much space available, we use RR selection between them.
2159         If not, then we pick the filesystem with the most space.
2160
2161         This gets a good balance between the two
2162         approaches.
2163         */
2164
2165         refresh_disk_space ();
2166
2167         int free_enough = 0;
2168
2169         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2170                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2171                         free_enough++;
2172                 }
2173         }
2174
2175         if (free_enough >= 2) {
2176                 /* use RR selection process, ensuring that the one
2177                    picked works OK.
2178                 */
2179
2180                 i = last_rr_session_dir;
2181
2182                 do {
2183                         if (++i == session_dirs.end()) {
2184                                 i = session_dirs.begin();
2185                         }
2186
2187                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2188                                 if (create_session_directory ((*i).path)) {
2189                                         result = (*i).path;
2190                                         last_rr_session_dir = i;
2191                                         return result;
2192                                 }
2193                         }
2194
2195                 } while (i != last_rr_session_dir);
2196
2197         } else {
2198
2199                 /* pick FS with the most freespace (and that
2200                    seems to actually work ...)
2201                 */
2202
2203                 vector<space_and_path> sorted;
2204                 space_and_path_ascending_cmp cmp;
2205
2206                 sorted = session_dirs;
2207                 sort (sorted.begin(), sorted.end(), cmp);
2208
2209                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2210                         if (create_session_directory ((*i).path)) {
2211                                 result = (*i).path;
2212                                 last_rr_session_dir = i;
2213                                 return result;
2214                         }
2215                 }
2216         }
2217
2218         return result;
2219 }
2220
2221 int
2222 Session::load_named_selections (const XMLNode& node)
2223 {
2224         XMLNodeList nlist;
2225         XMLNodeConstIterator niter;
2226         NamedSelection *ns;
2227
2228         nlist = node.children();
2229
2230         set_dirty();
2231
2232         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2233
2234                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2235                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2236                 }
2237         }
2238
2239         return 0;
2240 }
2241
2242 NamedSelection *
2243 Session::XMLNamedSelectionFactory (const XMLNode& node)
2244 {
2245         try {
2246                 return new NamedSelection (*this, node);
2247         }
2248
2249         catch (failed_constructor& err) {
2250                 return 0;
2251         }
2252 }
2253
2254 string
2255 Session::automation_dir () const
2256 {
2257         return Glib::build_filename (_path, "automation");
2258 }
2259
2260 string
2261 Session::analysis_dir () const
2262 {
2263         return Glib::build_filename (_path, "analysis");
2264 }
2265
2266 string
2267 Session::plugins_dir () const
2268 {
2269         return Glib::build_filename (_path, "plugins");
2270 }
2271
2272 string
2273 Session::externals_dir () const
2274 {
2275         return Glib::build_filename (_path, "externals");
2276 }
2277
2278 int
2279 Session::load_bundles (XMLNode const & node)
2280 {
2281         XMLNodeList nlist = node.children();
2282         XMLNodeConstIterator niter;
2283
2284         set_dirty();
2285
2286         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2287                 if ((*niter)->name() == "InputBundle") {
2288                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2289                 } else if ((*niter)->name() == "OutputBundle") {
2290                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2291                 } else {
2292                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2293                         return -1;
2294                 }
2295         }
2296
2297         return 0;
2298 }
2299
2300 int
2301 Session::load_route_groups (const XMLNode& node, int version)
2302 {
2303         XMLNodeList nlist = node.children();
2304         XMLNodeConstIterator niter;
2305
2306         set_dirty ();
2307
2308         if (version >= 3000) {
2309
2310                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2311                         if ((*niter)->name() == "RouteGroup") {
2312                                 RouteGroup* rg = new RouteGroup (*this, "");
2313                                 add_route_group (rg);
2314                                 rg->set_state (**niter, version);
2315                         }
2316                 }
2317
2318         } else if (version < 3000) {
2319
2320                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2321                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2322                                 RouteGroup* rg = new RouteGroup (*this, "");
2323                                 add_route_group (rg);
2324                                 rg->set_state (**niter, version);
2325                         }
2326                 }
2327         }
2328
2329         return 0;
2330 }
2331
2332 void
2333 Session::auto_save()
2334 {
2335         save_state (_current_snapshot_name);
2336 }
2337
2338 static bool
2339 state_file_filter (const string &str, void */*arg*/)
2340 {
2341         return (str.length() > strlen(statefile_suffix) &&
2342                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2343 }
2344
2345 struct string_cmp {
2346         bool operator()(const string* a, const string* b) {
2347                 return *a < *b;
2348         }
2349 };
2350
2351 static string*
2352 remove_end(string* state)
2353 {
2354         string statename(*state);
2355
2356         string::size_type start,end;
2357         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2358                 statename = statename.substr (start+1);
2359         }
2360
2361         if ((end = statename.rfind(".ardour")) == string::npos) {
2362                 end = statename.length();
2363         }
2364
2365         return new string(statename.substr (0, end));
2366 }
2367
2368 vector<string *> *
2369 Session::possible_states (string path)
2370 {
2371         PathScanner scanner;
2372         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2373
2374         transform(states->begin(), states->end(), states->begin(), remove_end);
2375
2376         string_cmp cmp;
2377         sort (states->begin(), states->end(), cmp);
2378
2379         return states;
2380 }
2381
2382 vector<string *> *
2383 Session::possible_states () const
2384 {
2385         return possible_states(_path);
2386 }
2387
2388 void
2389 Session::add_route_group (RouteGroup* g)
2390 {
2391         _route_groups.push_back (g);
2392         route_group_added (g); /* EMIT SIGNAL */
2393
2394         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2395         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2396         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2397
2398         set_dirty ();
2399 }
2400
2401 void
2402 Session::remove_route_group (RouteGroup& rg)
2403 {
2404         list<RouteGroup*>::iterator i;
2405
2406         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2407                 _route_groups.erase (i);
2408                 delete &rg;
2409
2410                 route_group_removed (); /* EMIT SIGNAL */
2411         }
2412 }
2413
2414 /** Set a new order for our route groups, without adding or removing any.
2415  *  @param groups Route group list in the new order.
2416  */
2417 void
2418 Session::reorder_route_groups (list<RouteGroup*> groups)
2419 {
2420         _route_groups = groups;
2421
2422         route_groups_reordered (); /* EMIT SIGNAL */
2423         set_dirty ();
2424 }
2425
2426
2427 RouteGroup *
2428 Session::route_group_by_name (string name)
2429 {
2430         list<RouteGroup *>::iterator i;
2431
2432         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2433                 if ((*i)->name() == name) {
2434                         return* i;
2435                 }
2436         }
2437         return 0;
2438 }
2439
2440 RouteGroup&
2441 Session::all_route_group() const
2442 {
2443         return *_all_route_group;
2444 }
2445
2446 void
2447 Session::add_commands (vector<Command*> const & cmds)
2448 {
2449         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2450                 add_command (*i);
2451         }
2452 }
2453
2454 void
2455 Session::begin_reversible_command (const string& name)
2456 {
2457         begin_reversible_command (g_quark_from_string (name.c_str ()));
2458 }
2459
2460 /** Begin a reversible command using a GQuark to identify it.
2461  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2462  *  but there must be as many begin...()s as there are commit...()s.
2463  */
2464 void
2465 Session::begin_reversible_command (GQuark q)
2466 {
2467         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2468            to hold all the commands that are committed.  This keeps the order of
2469            commands correct in the history.
2470         */
2471
2472         if (_current_trans == 0) {
2473                 /* start a new transaction */
2474                 assert (_current_trans_quarks.empty ());
2475                 _current_trans = new UndoTransaction();
2476                 _current_trans->set_name (g_quark_to_string (q));
2477         }
2478
2479         _current_trans_quarks.push_front (q);
2480 }
2481
2482 void
2483 Session::commit_reversible_command (Command *cmd)
2484 {
2485         assert (_current_trans);
2486         assert (!_current_trans_quarks.empty ());
2487
2488         struct timeval now;
2489
2490         if (cmd) {
2491                 _current_trans->add_command (cmd);
2492         }
2493
2494         _current_trans_quarks.pop_front ();
2495
2496         if (!_current_trans_quarks.empty ()) {
2497                 /* the transaction we're committing is not the top-level one */
2498                 return;
2499         }
2500
2501         if (_current_trans->empty()) {
2502                 /* no commands were added to the transaction, so just get rid of it */
2503                 delete _current_trans;
2504                 _current_trans = 0;
2505                 return;
2506         }
2507
2508         gettimeofday (&now, 0);
2509         _current_trans->set_timestamp (now);
2510
2511         _history.add (_current_trans);
2512         _current_trans = 0;
2513 }
2514
2515 static bool
2516 accept_all_audio_files (const string& path, void */*arg*/)
2517 {
2518         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2519                 return false;
2520         }
2521
2522         if (!AudioFileSource::safe_audio_file_extension (path)) {
2523                 return false;
2524         }
2525
2526         return true;
2527 }
2528
2529 static bool
2530 accept_all_midi_files (const string& path, void */*arg*/)
2531 {
2532         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2533                 return false;
2534         }
2535
2536         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2537                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2538                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2539 }
2540
2541 static bool
2542 accept_all_state_files (const string& path, void */*arg*/)
2543 {
2544         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2545                 return false;
2546         }
2547
2548         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2549 }
2550
2551 int
2552 Session::find_all_sources (string path, set<string>& result)
2553 {
2554         XMLTree tree;
2555         XMLNode* node;
2556
2557         if (!tree.read (path)) {
2558                 return -1;
2559         }
2560
2561         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2562                 return -2;
2563         }
2564
2565         XMLNodeList nlist;
2566         XMLNodeConstIterator niter;
2567
2568         nlist = node->children();
2569
2570         set_dirty();
2571
2572         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2573
2574                 XMLProperty* prop;
2575
2576                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2577                         continue;
2578                 }
2579
2580                 DataType type (prop->value());
2581
2582                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2583                         continue;
2584                 }
2585
2586                 if (Glib::path_is_absolute (prop->value())) {
2587                         /* external file, ignore */
2588                         continue;
2589                 }
2590
2591                 string found_path;
2592                 bool is_new;
2593                 uint16_t chan;
2594
2595                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2596                         result.insert (found_path);
2597                 }
2598         }
2599
2600         return 0;
2601 }
2602
2603 int
2604 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2605 {
2606         PathScanner scanner;
2607         vector<string*>* state_files;
2608         string ripped;
2609         string this_snapshot_path;
2610
2611         result.clear ();
2612
2613         ripped = _path;
2614
2615         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2616                 ripped = ripped.substr (0, ripped.length() - 1);
2617         }
2618
2619         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2620
2621         if (state_files == 0) {
2622                 /* impossible! */
2623                 return 0;
2624         }
2625
2626         this_snapshot_path = _path;
2627         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2628         this_snapshot_path += statefile_suffix;
2629
2630         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2631
2632                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2633                         continue;
2634                 }
2635
2636                 if (find_all_sources (**i, result) < 0) {
2637                         return -1;
2638                 }
2639         }
2640
2641         return 0;
2642 }
2643
2644 struct RegionCounter {
2645     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2646     AudioSourceList::iterator iter;
2647     boost::shared_ptr<Region> region;
2648     uint32_t count;
2649
2650     RegionCounter() : count (0) {}
2651 };
2652
2653 int
2654 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2655 {
2656         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2657         return r.get_value_or (1);
2658 }
2659
2660 void
2661 Session::cleanup_regions ()
2662 {
2663         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2664
2665         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2666
2667                 uint32_t used = playlists->region_use_count (i->second);
2668
2669                 if (used == 0 && !i->second->automatic ()) {
2670                         RegionFactory::map_remove (i->second);
2671                 }
2672         }
2673
2674         /* dump the history list */
2675         _history.clear ();
2676
2677         save_state ("");
2678 }
2679
2680 int
2681 Session::cleanup_sources (CleanupReport& rep)
2682 {
2683         // FIXME: needs adaptation to midi
2684
2685         vector<boost::shared_ptr<Source> > dead_sources;
2686         PathScanner scanner;
2687         string audio_path;
2688         string midi_path;
2689         vector<space_and_path>::iterator i;
2690         vector<space_and_path>::iterator nexti;
2691         vector<string*>* candidates;
2692         vector<string*>* candidates2;
2693         vector<string> unused;
2694         set<string> all_sources;
2695         bool used;
2696         string spath;
2697         int ret = -1;
2698
2699         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2700
2701         /* consider deleting all unused playlists */
2702
2703         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2704                 ret = 0;
2705                 goto out;
2706         }
2707
2708         /* sync the "all regions" property of each playlist with its current state
2709          */
2710
2711         playlists->sync_all_regions_with_regions ();
2712
2713         /* find all un-used sources */
2714
2715         rep.paths.clear ();
2716         rep.space = 0;
2717
2718         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2719
2720                 SourceMap::iterator tmp;
2721
2722                 tmp = i;
2723                 ++tmp;
2724
2725                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2726                    capture files.
2727                 */
2728
2729                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2730                         dead_sources.push_back (i->second);
2731                         i->second->drop_references ();
2732                 }
2733
2734                 i = tmp;
2735         }
2736
2737         /* build a list of all the possible audio directories for the session */
2738
2739         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2740
2741                 nexti = i;
2742                 ++nexti;
2743
2744                 SessionDirectory sdir ((*i).path);
2745                 audio_path += sdir.sound_path();
2746
2747                 if (nexti != session_dirs.end()) {
2748                         audio_path += ':';
2749                 }
2750
2751                 i = nexti;
2752         }
2753
2754
2755         /* build a list of all the possible midi directories for the session */
2756
2757         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2758
2759                 nexti = i;
2760                 ++nexti;
2761
2762                 SessionDirectory sdir ((*i).path);
2763                 midi_path += sdir.midi_path();
2764
2765                 if (nexti != session_dirs.end()) {
2766                         midi_path += ':';
2767                 }
2768
2769                 i = nexti;
2770         }
2771
2772         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2773         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2774
2775         /* merge them */
2776
2777         if (candidates) {
2778                 if (candidates2) {
2779                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2780                                 candidates->push_back (*i);
2781                         }
2782                         delete candidates2;
2783                 }
2784         } else {
2785                 candidates = candidates2; // might still be null
2786         }
2787
2788         /* find all sources, but don't use this snapshot because the
2789            state file on disk still references sources we may have already
2790            dropped.
2791         */
2792
2793         find_all_sources_across_snapshots (all_sources, true);
2794
2795         /*  add our current source list
2796          */
2797
2798         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2799                 boost::shared_ptr<FileSource> fs;
2800                 SourceMap::iterator tmp = i;
2801                 ++tmp;
2802
2803                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2804                         if (playlists->source_use_count (fs) != 0) {
2805                                 all_sources.insert (fs->path());
2806                         } else {
2807
2808                                 /* we might not remove this source from disk, because it may be used
2809                                    by other snapshots, but its not being used in this version
2810                                    so lets get rid of it now, along with any representative regions
2811                                    in the region list.
2812                                 */
2813
2814                                 RegionFactory::remove_regions_using_source (i->second);
2815                                 sources.erase (i);
2816                         }
2817                 }
2818
2819                 i = tmp;
2820         }
2821
2822         char tmppath1[PATH_MAX+1];
2823         char tmppath2[PATH_MAX+1];
2824
2825         if (candidates) {
2826                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2827
2828                         used = false;
2829                         spath = **x;
2830
2831                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2832
2833                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2834                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2835                                                                  spath, strerror (errno)) << endmsg;
2836                                         continue;
2837                                 }
2838
2839                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2840                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2841                                                                  (*i), strerror (errno)) << endmsg;
2842                                         continue;
2843                                 }
2844
2845                                 if (strcmp(tmppath1, tmppath2) == 0) {
2846                                         used = true;
2847                                         break;
2848                                 }
2849                         }
2850
2851                         if (!used) {
2852                                 unused.push_back (spath);
2853                         }
2854
2855                         delete *x;
2856                 }
2857
2858                 delete candidates;
2859         }
2860
2861         /* now try to move all unused files into the "dead" directory(ies) */
2862
2863         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2864                 struct stat statbuf;
2865
2866                 string newpath;
2867
2868                 /* don't move the file across filesystems, just
2869                    stick it in the `dead_dir_name' directory
2870                    on whichever filesystem it was already on.
2871                 */
2872
2873                 if ((*x).find ("/sounds/") != string::npos) {
2874
2875                         /* old school, go up 1 level */
2876
2877                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2878                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2879
2880                 } else {
2881
2882                         /* new school, go up 4 levels */
2883
2884                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2885                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2886                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2887                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2888                 }
2889
2890                 newpath = Glib::build_filename (newpath, dead_dir_name);
2891
2892                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2893                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2894                         return -1;
2895                 }
2896
2897                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2898
2899                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2900
2901                         /* the new path already exists, try versioning */
2902
2903                         char buf[PATH_MAX+1];
2904                         int version = 1;
2905                         string newpath_v;
2906
2907                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2908                         newpath_v = buf;
2909
2910                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2911                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2912                                 newpath_v = buf;
2913                         }
2914
2915                         if (version == 999) {
2916                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2917                                                   newpath)
2918                                       << endmsg;
2919                         } else {
2920                                 newpath = newpath_v;
2921                         }
2922
2923                 } else {
2924
2925                         /* it doesn't exist, or we can't read it or something */
2926
2927                 }
2928
2929                 stat ((*x).c_str(), &statbuf);
2930
2931                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2932                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2933                                           (*x), newpath, strerror (errno))
2934                               << endmsg;
2935                         goto out;
2936                 }
2937
2938                 /* see if there an easy to find peakfile for this file, and remove it.
2939                  */
2940
2941                 string base = basename_nosuffix (*x);
2942                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2943                                  or for the first channel of embedded files. it will miss
2944                                  some peakfiles for other channels
2945                               */
2946                 string peakpath = peak_path (base);
2947
2948                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2949                         if (::unlink (peakpath.c_str()) != 0) {
2950                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2951                                                          peakpath, _path, strerror (errno))
2952                                       << endmsg;
2953                                 /* try to back out */
2954                                 ::rename (newpath.c_str(), _path.c_str());
2955                                 goto out;
2956                         }
2957                 }
2958
2959                 rep.paths.push_back (*x);
2960                 rep.space += statbuf.st_size;
2961         }
2962
2963         /* dump the history list */
2964
2965         _history.clear ();
2966
2967         /* save state so we don't end up a session file
2968            referring to non-existent sources.
2969         */
2970
2971         save_state ("");
2972         ret = 0;
2973
2974   out:
2975         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2976
2977         return ret;
2978 }
2979
2980 int
2981 Session::cleanup_trash_sources (CleanupReport& rep)
2982 {
2983         // FIXME: needs adaptation for MIDI
2984
2985         vector<space_and_path>::iterator i;
2986         string dead_dir;
2987
2988         rep.paths.clear ();
2989         rep.space = 0;
2990
2991         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2992
2993                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2994
2995                 clear_directory (dead_dir, &rep.space, &rep.paths);
2996         }
2997
2998         return 0;
2999 }
3000
3001 void
3002 Session::set_dirty ()
3003 {
3004         bool was_dirty = dirty();
3005
3006         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3007
3008
3009         if (!was_dirty) {
3010                 DirtyChanged(); /* EMIT SIGNAL */
3011         }
3012 }
3013
3014
3015 void
3016 Session::set_clean ()
3017 {
3018         bool was_dirty = dirty();
3019
3020         _state_of_the_state = Clean;
3021
3022
3023         if (was_dirty) {
3024                 DirtyChanged(); /* EMIT SIGNAL */
3025         }
3026 }
3027
3028 void
3029 Session::set_deletion_in_progress ()
3030 {
3031         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3032 }
3033
3034 void
3035 Session::clear_deletion_in_progress ()
3036 {
3037         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3038 }
3039
3040 void
3041 Session::add_controllable (boost::shared_ptr<Controllable> c)
3042 {
3043         /* this adds a controllable to the list managed by the Session.
3044            this is a subset of those managed by the Controllable class
3045            itself, and represents the only ones whose state will be saved
3046            as part of the session.
3047         */
3048
3049         Glib::Mutex::Lock lm (controllables_lock);
3050         controllables.insert (c);
3051 }
3052
3053 struct null_deleter { void operator()(void const *) const {} };
3054
3055 void
3056 Session::remove_controllable (Controllable* c)
3057 {
3058         if (_state_of_the_state & Deletion) {
3059                 return;
3060         }
3061
3062         Glib::Mutex::Lock lm (controllables_lock);
3063
3064         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3065
3066         if (x != controllables.end()) {
3067                 controllables.erase (x);
3068         }
3069 }
3070
3071 boost::shared_ptr<Controllable>
3072 Session::controllable_by_id (const PBD::ID& id)
3073 {
3074         Glib::Mutex::Lock lm (controllables_lock);
3075
3076         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3077                 if ((*i)->id() == id) {
3078                         return *i;
3079                 }
3080         }
3081
3082         return boost::shared_ptr<Controllable>();
3083 }
3084
3085 boost::shared_ptr<Controllable>
3086 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3087 {
3088         boost::shared_ptr<Controllable> c;
3089         boost::shared_ptr<Route> r;
3090
3091         switch (desc.top_level_type()) {
3092         case ControllableDescriptor::NamedRoute:
3093         {
3094                 std::string str = desc.top_level_name();
3095                 if (str == "master") {
3096                         r = _master_out;
3097                 } else if (str == "control" || str == "listen") {
3098                         r = _monitor_out;
3099                 } else {
3100                         r = route_by_name (desc.top_level_name());
3101                 }
3102                 break;
3103         }
3104
3105         case ControllableDescriptor::RemoteControlID:
3106                 r = route_by_remote_id (desc.rid());
3107                 break;
3108         }
3109
3110         if (!r) {
3111                 return c;
3112         }
3113
3114         switch (desc.subtype()) {
3115         case ControllableDescriptor::Gain:
3116                 c = r->gain_control ();
3117                 break;
3118
3119         case ControllableDescriptor::Solo:
3120                 c = r->solo_control();
3121                 break;
3122
3123         case ControllableDescriptor::Mute:
3124                 c = r->mute_control();
3125                 break;
3126
3127         case ControllableDescriptor::Recenable:
3128         {
3129                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3130
3131                 if (t) {
3132                         c = t->rec_enable_control ();
3133                 }
3134                 break;
3135         }
3136
3137         case ControllableDescriptor::PanDirection:
3138         {
3139                 c = r->pannable()->pan_azimuth_control;
3140                 break;
3141         }
3142
3143         case ControllableDescriptor::PanWidth:
3144         {
3145                 c = r->pannable()->pan_width_control;
3146                 break;
3147         }
3148
3149         case ControllableDescriptor::PanElevation:
3150         {
3151                 c = r->pannable()->pan_elevation_control;
3152                 break;
3153         }
3154
3155         case ControllableDescriptor::Balance:
3156                 /* XXX simple pan control */
3157                 break;
3158
3159         case ControllableDescriptor::PluginParameter:
3160         {
3161                 uint32_t plugin = desc.target (0);
3162                 uint32_t parameter_index = desc.target (1);
3163
3164                 /* revert to zero based counting */
3165
3166                 if (plugin > 0) {
3167                         --plugin;
3168                 }
3169
3170                 if (parameter_index > 0) {
3171                         --parameter_index;
3172                 }
3173
3174                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3175
3176                 if (p) {
3177                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3178                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3179                 }
3180                 break;
3181         }
3182
3183         case ControllableDescriptor::SendGain:
3184         {
3185                 uint32_t send = desc.target (0);
3186
3187                 /* revert to zero-based counting */
3188
3189                 if (send > 0) {
3190                         --send;
3191                 }
3192
3193                 boost::shared_ptr<Processor> p = r->nth_send (send);
3194
3195                 if (p) {
3196                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3197                         boost::shared_ptr<Amp> a = s->amp();
3198
3199                         if (a) {
3200                                 c = s->amp()->gain_control();
3201                         }
3202                 }
3203                 break;
3204         }
3205
3206         default:
3207                 /* relax and return a null pointer */
3208                 break;
3209         }
3210
3211         return c;
3212 }
3213
3214 void
3215 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3216 {
3217         if (_writable) {
3218                 Stateful::add_instant_xml (node, _path);
3219         }
3220
3221         if (write_to_config) {
3222                 Config->add_instant_xml (node);
3223         }
3224 }
3225
3226 XMLNode*
3227 Session::instant_xml (const string& node_name)
3228 {
3229         return Stateful::instant_xml (node_name, _path);
3230 }
3231
3232 int
3233 Session::save_history (string snapshot_name)
3234 {
3235         XMLTree tree;
3236
3237         if (!_writable) {
3238                 return 0;
3239         }
3240
3241         if (snapshot_name.empty()) {
3242                 snapshot_name = _current_snapshot_name;
3243         }
3244
3245         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3246         const string backup_filename = history_filename + backup_suffix;
3247         const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3248         const sys::path backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3249
3250         if (sys::exists (xml_path)) {
3251                 try
3252                 {
3253                         sys::rename (xml_path, backup_path);
3254                 }
3255                 catch (const sys::filesystem_error& err)
3256                 {
3257                         error << _("could not backup old history file, current history not saved") << endmsg;
3258                         return -1;
3259                 }
3260         }
3261
3262         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3263                 return 0;
3264         }
3265
3266         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3267
3268         if (!tree.write (xml_path.to_string()))
3269         {
3270                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3271
3272                 try
3273                 {
3274                         sys::remove (xml_path);
3275                         sys::rename (backup_path, xml_path);
3276                 }
3277                 catch (const sys::filesystem_error& err)
3278                 {
3279                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3280                                         backup_path.to_string(), err.what()) << endmsg;
3281                 }
3282
3283                 return -1;
3284         }
3285
3286         return 0;
3287 }
3288
3289 int
3290 Session::restore_history (string snapshot_name)
3291 {
3292         XMLTree tree;
3293
3294         if (snapshot_name.empty()) {
3295                 snapshot_name = _current_snapshot_name;
3296         }
3297
3298         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3299         const sys::path xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3300
3301         info << "Loading history from " << xml_path.to_string() << endmsg;
3302
3303         if (!sys::exists (xml_path)) {
3304                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3305                                 _name, xml_path.to_string()) << endmsg;
3306                 return 1;
3307         }
3308
3309         if (!tree.read (xml_path.to_string())) {
3310                 error << string_compose (_("Could not understand session history file \"%1\""),
3311                                 xml_path.to_string()) << endmsg;
3312                 return -1;
3313         }
3314
3315         // replace history
3316         _history.clear();
3317
3318         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3319
3320                 XMLNode *t = *it;
3321                 UndoTransaction* ut = new UndoTransaction ();
3322                 struct timeval tv;
3323
3324                 ut->set_name(t->property("name")->value());
3325                 stringstream ss(t->property("tv-sec")->value());
3326                 ss >> tv.tv_sec;
3327                 ss.str(t->property("tv-usec")->value());
3328                 ss >> tv.tv_usec;
3329                 ut->set_timestamp(tv);
3330
3331                 for (XMLNodeConstIterator child_it  = t->children().begin();
3332                                 child_it != t->children().end(); child_it++)
3333                 {
3334                         XMLNode *n = *child_it;
3335                         Command *c;
3336
3337                         if (n->name() == "MementoCommand" ||
3338                                         n->name() == "MementoUndoCommand" ||
3339                                         n->name() == "MementoRedoCommand") {
3340
3341                                 if ((c = memento_command_factory(n))) {
3342                                         ut->add_command(c);
3343                                 }
3344
3345                         } else if (n->name() == "NoteDiffCommand") {
3346                                 PBD::ID id (n->property("midi-source")->value());
3347                                 boost::shared_ptr<MidiSource> midi_source =
3348                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3349                                 if (midi_source) {
3350                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3351                                 } else {
3352                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3353                                 }
3354
3355                         } else if (n->name() == "SysExDiffCommand") {
3356
3357                                 PBD::ID id (n->property("midi-source")->value());
3358                                 boost::shared_ptr<MidiSource> midi_source =
3359                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3360                                 if (midi_source) {
3361                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3362                                 } else {
3363                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3364                                 }
3365
3366                         } else if (n->name() == "PatchChangeDiffCommand") {
3367
3368                                 PBD::ID id (n->property("midi-source")->value());
3369                                 boost::shared_ptr<MidiSource> midi_source =
3370                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3371                                 if (midi_source) {
3372                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3373                                 } else {
3374                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3375                                 }
3376
3377                         } else if (n->name() == "StatefulDiffCommand") {
3378                                 if ((c = stateful_diff_command_factory (n))) {
3379                                         ut->add_command (c);
3380                                 }
3381                         } else {
3382                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3383                         }
3384                 }
3385
3386                 _history.add (ut);
3387         }
3388
3389         return 0;
3390 }
3391
3392 void
3393 Session::config_changed (std::string p, bool ours)
3394 {
3395         if (ours) {
3396                 set_dirty ();
3397         }
3398
3399         if (p == "seamless-loop") {
3400
3401         } else if (p == "rf-speed") {
3402
3403         } else if (p == "auto-loop") {
3404
3405         } else if (p == "auto-input") {
3406
3407                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3408                         /* auto-input only makes a difference if we're rolling */
3409                         set_track_monitor_input_status (!config.get_auto_input());
3410                 }
3411
3412         } else if (p == "punch-in") {
3413
3414                 Location* location;
3415
3416                 if ((location = _locations->auto_punch_location()) != 0) {
3417
3418                         if (config.get_punch_in ()) {
3419                                 replace_event (SessionEvent::PunchIn, location->start());
3420                         } else {
3421                                 remove_event (location->start(), SessionEvent::PunchIn);
3422                         }
3423                 }
3424
3425         } else if (p == "punch-out") {
3426
3427                 Location* location;
3428
3429                 if ((location = _locations->auto_punch_location()) != 0) {
3430
3431                         if (config.get_punch_out()) {
3432                                 replace_event (SessionEvent::PunchOut, location->end());
3433                         } else {
3434                                 clear_events (SessionEvent::PunchOut);
3435                         }
3436                 }
3437
3438         } else if (p == "edit-mode") {
3439
3440                 Glib::Mutex::Lock lm (playlists->lock);
3441
3442                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3443                         (*i)->set_edit_mode (Config->get_edit_mode ());
3444                 }
3445
3446         } else if (p == "use-video-sync") {
3447
3448                 waiting_for_sync_offset = config.get_use_video_sync();
3449
3450         } else if (p == "mmc-control") {
3451
3452                 //poke_midi_thread ();
3453
3454         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3455
3456                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3457
3458         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3459
3460                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3461
3462         } else if (p == "midi-control") {
3463
3464                 //poke_midi_thread ();
3465
3466         } else if (p == "raid-path") {
3467
3468                 setup_raid_path (config.get_raid_path());
3469
3470         } else if (p == "timecode-format") {
3471
3472                 sync_time_vars ();
3473
3474         } else if (p == "video-pullup") {
3475
3476                 sync_time_vars ();
3477
3478         } else if (p == "seamless-loop") {
3479
3480                 if (play_loop && transport_rolling()) {
3481                         // to reset diskstreams etc
3482                         request_play_loop (true);
3483                 }
3484
3485         } else if (p == "rf-speed") {
3486
3487                 cumulative_rf_motion = 0;
3488                 reset_rf_scale (0);
3489
3490         } else if (p == "click-sound") {
3491
3492                 setup_click_sounds (1);
3493
3494         } else if (p == "click-emphasis-sound") {
3495
3496                 setup_click_sounds (-1);
3497
3498         } else if (p == "clicking") {
3499
3500                 if (Config->get_clicking()) {
3501                         if (_click_io && click_data) { // don't require emphasis data
3502                                 _clicking = true;
3503                         }
3504                 } else {
3505                         _clicking = false;
3506                 }
3507
3508         } else if (p == "click-gain") {
3509                 
3510                 if (_click_gain) {
3511                         _click_gain->set_gain (Config->get_click_gain(), this);
3512                 }
3513
3514         } else if (p == "send-mtc") {
3515
3516                 if (Config->get_send_mtc ()) {
3517                         /* mark us ready to send */
3518                         next_quarter_frame_to_send = 0;
3519                 }
3520
3521         } else if (p == "send-mmc") {
3522
3523                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3524
3525         } else if (p == "midi-feedback") {
3526
3527                 session_midi_feedback = Config->get_midi_feedback();
3528
3529         } else if (p == "jack-time-master") {
3530
3531                 engine().reset_timebase ();
3532
3533         } else if (p == "native-file-header-format") {
3534
3535                 if (!first_file_header_format_reset) {
3536                         reset_native_file_format ();
3537                 }
3538
3539                 first_file_header_format_reset = false;
3540
3541         } else if (p == "native-file-data-format") {
3542
3543                 if (!first_file_data_format_reset) {
3544                         reset_native_file_format ();
3545                 }
3546
3547                 first_file_data_format_reset = false;
3548
3549         } else if (p == "external-sync") {
3550                 if (!config.get_external_sync()) {
3551                         drop_sync_source ();
3552                 } else {
3553                         switch_to_sync_source (config.get_sync_source());
3554                 }
3555         } else if (p == "remote-model") {
3556                 set_remote_control_ids ();
3557         }  else if (p == "denormal-model") {
3558                 setup_fpu ();
3559         } else if (p == "history-depth") {
3560                 set_history_depth (Config->get_history_depth());
3561         } else if (p == "sync-all-route-ordering") {
3562                 sync_order_keys ("session");
3563         } else if (p == "initial-program-change") {
3564
3565                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3566                         MIDI::byte buf[2];
3567
3568                         buf[0] = MIDI::program; // channel zero by default
3569                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3570
3571                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3572                 }
3573         } else if (p == "solo-mute-override") {
3574                 // catch_up_on_solo_mute_override ();
3575         } else if (p == "listen-position" || p == "pfl-position") {
3576                 listen_position_changed ();
3577         } else if (p == "solo-control-is-listen-control") {
3578                 solo_control_mode_changed ();
3579         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3580                 last_timecode_valid = false;
3581         } else if (p == "playback-buffer-seconds") {
3582                 AudioSource::allocate_working_buffers (frame_rate());
3583         } else if (p == "automation-thinning-factor") {
3584                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3585         }
3586
3587         set_dirty ();
3588 }
3589
3590 void
3591 Session::set_history_depth (uint32_t d)
3592 {
3593         _history.set_depth (d);
3594 }
3595
3596 int
3597 Session::load_diskstreams_2X (XMLNode const & node, int)
3598 {
3599         XMLNodeList          clist;
3600         XMLNodeConstIterator citer;
3601
3602         clist = node.children();
3603
3604         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3605
3606                 try {
3607                         /* diskstreams added automatically by DiskstreamCreated handler */
3608                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3609                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3610                                 _diskstreams_2X.push_back (dsp);
3611                         } else {
3612                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3613                         }
3614                 }
3615
3616                 catch (failed_constructor& err) {
3617                         error << _("Session: could not load diskstream via XML state") << endmsg;
3618                         return -1;
3619                 }
3620         }
3621
3622         return 0;
3623 }
3624
3625 /** Connect things to the MMC object */
3626 void
3627 Session::setup_midi_machine_control ()
3628 {
3629         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3630
3631         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3632         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3633         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3634         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3635         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3636         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3637         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3638         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3639         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3640         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3641         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3642         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3643         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3644
3645         /* also handle MIDI SPP because its so common */
3646
3647         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3648         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3649         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3650 }
3651
3652 boost::shared_ptr<Controllable>
3653 Session::solo_cut_control() const
3654 {
3655         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3656            controls in Ardour that currently get presented to the user in the GUI that require
3657            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3658
3659            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3660            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3661            parameter.
3662         */
3663
3664         return _solo_cut_control;
3665 }
3666
3667 int
3668 Session::rename (const std::string& new_name)
3669 {
3670         string legal_name = legalize_for_path (new_name);
3671         string newpath;
3672         string oldstr;
3673         string newstr;
3674         bool first = true;
3675
3676         string const old_sources_root = _session_dir->sources_root();
3677
3678 #define RENAME ::rename
3679
3680         /* Rename:
3681
3682          * session directory
3683          * interchange subdirectory
3684          * session file
3685          * session history
3686          
3687          * Backup files are left unchanged and not renamed.
3688          */
3689
3690         /* pass one: not 100% safe check that the new directory names don't
3691          * already exist ...
3692          */
3693
3694         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3695                 vector<string> v;
3696
3697                 oldstr = (*i).path;
3698
3699                 /* this is a stupid hack because Glib::path_get_dirname() is
3700                  * lexical-only, and so passing it /a/b/c/ gives a different
3701                  * result than passing it /a/b/c ...
3702                  */
3703
3704                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3705                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3706                 }
3707
3708                 string base = Glib::path_get_dirname (oldstr);
3709                 string p = Glib::path_get_basename (oldstr);
3710
3711                 newstr = Glib::build_filename (base, legal_name);
3712                 
3713                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3714                         return -1;
3715                 }
3716         }
3717
3718         /* Session dirs */
3719         
3720         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3721                 vector<string> v;
3722
3723                 oldstr = (*i).path;
3724
3725                 /* this is a stupid hack because Glib::path_get_dirname() is
3726                  * lexical-only, and so passing it /a/b/c/ gives a different
3727                  * result than passing it /a/b/c ...
3728                  */
3729
3730                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3731                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3732                 }
3733
3734                 string base = Glib::path_get_dirname (oldstr);
3735                 string p = Glib::path_get_basename (oldstr);
3736
3737                 newstr = Glib::build_filename (base, legal_name);
3738
3739                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3740
3741                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3742                         return 1;
3743                 }
3744
3745                 if (first) {
3746                         (*_session_dir) = newstr;
3747                         newpath = newstr;
3748                         first = 1;
3749                 }
3750
3751                 /* directory below interchange */
3752
3753                 v.push_back (newstr);
3754                 v.push_back (interchange_dir_name);
3755                 v.push_back (p);
3756
3757                 oldstr = Glib::build_filename (v);
3758
3759                 v.clear ();
3760                 v.push_back (newstr);
3761                 v.push_back (interchange_dir_name);
3762                 v.push_back (legal_name);
3763
3764                 newstr = Glib::build_filename (v);
3765                 
3766                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3767                 
3768                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3769                         return 1;
3770                 }
3771         }
3772
3773         /* state file */
3774         
3775         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3776         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3777         
3778         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3779
3780         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3781                 return 1;
3782         }
3783
3784         /* history file */
3785
3786         
3787         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3788
3789         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3790                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3791                 
3792                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3793                 
3794                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3795                         return 1;
3796                 }
3797         }
3798
3799         /* update file source paths */
3800         
3801         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3802                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3803                 if (fs) {
3804                         string p = fs->path ();
3805                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3806                         fs->set_path (p);
3807                 }
3808         }
3809
3810         /* remove old name from recent sessions */
3811
3812         remove_recent_sessions (_path);
3813
3814         _path = newpath;
3815         _current_snapshot_name = new_name;
3816         _name = new_name;
3817
3818         set_dirty ();
3819
3820         /* save state again to get everything just right */
3821
3822         save_state (_current_snapshot_name);
3823
3824
3825         /* add to recent sessions */
3826
3827         store_recent_sessions (new_name, _path);
3828
3829         return 0;
3830
3831 #undef RENAME
3832 }