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