+
+/** Ensure that this source has some file on disk, even if it's just a SMF header */
+void
+SMFSource::ensure_disk_file ()
+{
+ if (_model) {
+ /* We have a model, so write it to disk; see MidiSource::session_saved
+ for an explanation of what we are doing here.
+ */
+ boost::shared_ptr<MidiModel> mm = _model;
+ _model.reset ();
+ mm->sync_to_source ();
+ _model = mm;
+ } else {
+ /* No model; if it's not already open, it's an empty source, so create
+ and open it for writing.
+ */
+ if (!_open) {
+ open_for_write ();
+ }
+
+ /* Flush, which will definitely put something on disk */
+ flush_midi ();
+ }
+}
+
+void
+SMFSource::prevent_deletion ()
+{
+ /* Unlike the audio case, the MIDI file remains mutable (because we can
+ edit MIDI data)
+ */
+
+ _flags = Flag (_flags & ~(Removable|RemovableIfEmpty|RemoveAtDestroy));
+}
+
+int
+SMFSource::rename (const string& newname)
+{
+ Glib::Threads::Mutex::Lock lm (_lock);
+ string oldpath = _path;
+ string newpath = _session.new_source_path_from_name (DataType::MIDI, newname);
+
+ if (newpath.empty()) {
+ error << string_compose (_("programming error: %1"), "cannot generate a changed file path") << endmsg;
+ return -1;
+ }
+
+ // Test whether newpath exists, if yes notify the user but continue.
+ if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
+ error << string_compose (_("Programming error! %1 tried to rename a file over another file! It's safe to continue working, but please report this to the developers."), PROGRAM_NAME) << endmsg;
+ return -1;
+ }
+
+ if (Glib::file_test (oldpath.c_str(), Glib::FILE_TEST_EXISTS)) {
+ /* rename only needed if file exists on disk */
+ if (::rename (oldpath.c_str(), newpath.c_str()) != 0) {
+ error << string_compose (_("cannot rename file %1 to %2 (%3)"), oldpath, newpath, strerror(errno)) << endmsg;
+ return -1;
+ }
+ }
+
+ _name = Glib::path_get_basename (newpath);
+ _path = newpath;
+
+ return 0;
+}