diff options
-rw-r--r-- | gtk2_ardour/actions.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/actions.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 10 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_dialogs.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui_ed.cc | 12 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/mixer_strip.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/route_time_axis.cc | 1 | ||||
-rw-r--r-- | gtk2_ardour/route_ui.cc | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/audiofilesource.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 5 | ||||
-rw-r--r-- | libs/ardour/audio_diskstream.cc | 2 | ||||
-rw-r--r-- | libs/ardour/audiofilesource.cc | 25 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 27 | ||||
-rw-r--r-- | libs/ardour/track.cc | 4 |
15 files changed, 78 insertions, 21 deletions
diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc index 9772081572..3db55b60d5 100644 --- a/gtk2_ardour/actions.cc +++ b/gtk2_ardour/actions.cc @@ -45,6 +45,7 @@ using namespace PBD; using namespace ARDOUR; vector<RefPtr<Gtk::Action> > ActionManager::session_sensitive_actions; +vector<RefPtr<Gtk::Action> > ActionManager::write_sensitive_actions; vector<RefPtr<Gtk::Action> > ActionManager::region_list_selection_sensitive_actions; vector<RefPtr<Gtk::Action> > ActionManager::plugin_selection_sensitive_actions; vector<RefPtr<Gtk::Action> > ActionManager::region_selection_sensitive_actions; diff --git a/gtk2_ardour/actions.h b/gtk2_ardour/actions.h index 0ff45a7a10..c84ad2c15b 100644 --- a/gtk2_ardour/actions.h +++ b/gtk2_ardour/actions.h @@ -42,6 +42,7 @@ class ActionManager static void init (); static std::vector<Glib::RefPtr<Gtk::Action> > session_sensitive_actions; + static std::vector<Glib::RefPtr<Gtk::Action> > write_sensitive_actions; static std::vector<Glib::RefPtr<Gtk::Action> > region_list_selection_sensitive_actions; static std::vector<Glib::RefPtr<Gtk::Action> > plugin_selection_sensitive_actions; diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 0accfe403d..4e16c40ab1 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -2483,16 +2483,6 @@ ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_na goto out; } - /* if it already exists, we must have write access */ - - if (Glib::file_test (path.c_str(), Glib::FILE_TEST_EXISTS) && ::access (path.c_str(), W_OK)) { - MessageDialog msg (*editor, _("You do not have write access to this session.\n" - "This prevents the session from being loaded.")); - pop_back_splash (); - msg.run (); - goto out; - } - loading_message (_("Please wait while Ardour loads your session")); try { diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 239327229b..b96e832a0e 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -56,6 +56,7 @@ ARDOUR_UI::connect_to_session (Session *s) /* sensitize menu bar options that are now valid */ ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true); + ActionManager::set_sensitive (ActionManager::write_sensitive_actions, session->writable()); if (session->locations()->num_range_markers()) { ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index fc016acb53..4ce02b8ea7 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -89,8 +89,8 @@ ARDOUR_UI::install_actions () /* menus + submenus that need action items */ ActionManager::register_action (main_actions, X_("Session"), _("Session")); - ActionManager::register_action (main_actions, X_("Files"), _("Import/Export")); - ActionManager::register_action (main_actions, X_("Cleanup"), _("Cleanup")); + act = ActionManager::register_action (main_actions, X_("Cleanup"), _("Cleanup")); + ActionManager::write_sensitive_actions.push_back (act); ActionManager::register_action (main_actions, X_("Sync"), _("Sync")); ActionManager::register_action (main_actions, X_("Options"), _("Options")); ActionManager::register_action (main_actions, X_("TransportOptions"), _("Options")); @@ -117,7 +117,7 @@ ARDOUR_UI::install_actions () act = ActionManager::register_action (main_actions, X_("AddTrackBus"), _("Add Track/Bus"), bind (mem_fun(*this, &ARDOUR_UI::add_route), (Gtk::Window*) 0)); ActionManager::session_sensitive_actions.push_back (act); - + ActionManager::write_sensitive_actions.push_back (act); /* <CMT Additions> */ @@ -136,6 +136,7 @@ ARDOUR_UI::install_actions () act = ActionManager::register_action (main_actions, X_("Snapshot"), _("Snapshot"), mem_fun(*this, &ARDOUR_UI::snapshot_session)); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); act = ActionManager::register_action (main_actions, X_("SaveTemplate"), _("Save Template..."), mem_fun(*this, &ARDOUR_UI::save_template)); ActionManager::session_sensitive_actions.push_back (act); @@ -156,8 +157,10 @@ ARDOUR_UI::install_actions () act = ActionManager::register_action (main_actions, X_("CleanupUnused"), _("Cleanup unused sources"), mem_fun (*(ARDOUR_UI::instance()), &ARDOUR_UI::cleanup)); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); act = ActionManager::register_action (main_actions, X_("FlushWastebasket"), _("Flush wastebasket"), mem_fun (*(ARDOUR_UI::instance()), &ARDOUR_UI::flush_trash)); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); /* JACK actions for controlling ... JACK */ @@ -225,6 +228,7 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (common_actions, X_("Save"), _("Save"), bind (mem_fun(*this, &ARDOUR_UI::save_state), string(""))); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); act = ActionManager::register_action (common_actions, X_("RemoveLastCapture"), _("Remove Last Capture"), mem_fun(*this, &ARDOUR_UI::remove_last_capture)); ActionManager::session_sensitive_actions.push_back (act); @@ -276,8 +280,10 @@ ARDOUR_UI::install_actions () act = ActionManager::register_action (transport_actions, X_("Record"), _("Enable Record"), bind (mem_fun(*this, &ARDOUR_UI::transport_record), false)); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); act = ActionManager::register_action (transport_actions, X_("record-roll"), _("Start Recording"), bind (mem_fun(*this, &ARDOUR_UI::transport_record), true)); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); act = ActionManager::register_action (transport_actions, X_("Rewind"), _("Rewind"), bind (mem_fun(*this, &ARDOUR_UI::transport_rewind), 0)); ActionManager::session_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index d9afdc2c23..f50934fe3e 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -796,10 +796,12 @@ Editor::register_actions () /* the next two are duplicate items with different names for use in two different contexts */ - ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Import"), mem_fun (*this, &Editor::external_audio_dialog)); + act = ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Import"), mem_fun (*this, &Editor::external_audio_dialog)); + ActionManager::write_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Import to Region List"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion)); ActionManager::session_sensitive_actions.push_back (act); + ActionManager::write_sensitive_actions.push_back (act); act = ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-visible"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility)); act = ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-rectified"), _("Show Waveforms Rectified"), mem_fun (*this, &Editor::toggle_waveform_rectified)); diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index da94788c0d..400e865a2e 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -377,6 +377,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt) #endif /* VARISPEED_IN_MIXER_STRIP */ button_table.attach (*rec_enable_button, 0, 2, 2, 3); + rec_enable_button->set_sensitive (_session.writable()); rec_enable_button->show(); } diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 63abdc2516..3127f71203 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -172,6 +172,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record")); + rec_enable_button->set_sensitive (_session.writable()); } controls_hbox.pack_start(gm.get_level_meter(), false, false); diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 107dd6baf8..c582a427d9 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -170,7 +170,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp) update_solo_display (); update_mute_display (); - if (is_track()) { + if (_session.writable() && is_track()) { boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route); connections.push_back (t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed))); diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index e363415362..a3cebd1b35 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -169,7 +169,7 @@ class AudioFileSource : public AudioSource { virtual void set_header_timeline_position () = 0; bool removable() const; - bool writable() const { return _flags & Writable; } + bool writable() const; static Sample* get_interleave_buffer (nframes_t size); @@ -177,6 +177,7 @@ class AudioFileSource : public AudioSource { Glib::ustring old_peak_path (Glib::ustring audio_path); Glib::ustring broken_peak_path (Glib::ustring audio_path); + void fix_writable_flags (); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index eb806c8b7f..90badcf9a4 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -241,7 +241,8 @@ class Session : public PBD::StatefulDestructible string export_dir () const; void set_snap_name (); - + + bool writable() const { return _writable; } void set_dirty (); void set_clean (); bool dirty() const { return _state_of_the_state & Dirty; } @@ -1003,6 +1004,8 @@ class Session : public PBD::StatefulDestructible nframes_t compute_initial_length (); + bool _writable; + static const char* _template_suffix; static const char* _statefile_suffix; static const char* _pending_suffix; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 4310e56b1b..44aca0980f 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -2095,7 +2095,7 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force) boost::shared_ptr<ChannelList> c = channels.reader(); uint32_t n; - if (!recordable()) { + if (!_session.writable() || !recordable()) { return; } diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index b506924513..ad132f219f 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -96,6 +96,7 @@ AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags) throw failed_constructor (); } + fix_writable_flags (); } AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format) @@ -108,6 +109,8 @@ AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags, SampleFo if (init (path, false)) { throw failed_constructor (); } + + fix_writable_flags (); } AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exist) @@ -125,6 +128,8 @@ AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exi if (init (foo, must_exist)) { throw failed_constructor (); } + + fix_writable_flags (); } AudioFileSource::~AudioFileSource () @@ -135,6 +140,14 @@ AudioFileSource::~AudioFileSource () } } +void +AudioFileSource::fix_writable_flags () +{ + if (!_session.writable()) { + _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); + } +} + bool AudioFileSource::determine_embeddedness (ustring path) { @@ -147,6 +160,12 @@ AudioFileSource::removable () const return (_flags & Removable) && ((_flags & RemoveAtDestroy) || ((_flags & RemovableIfEmpty) && length() == 0)); } +bool +AudioFileSource::writable() const +{ + return (_flags & Writable); +} + int AudioFileSource::init (ustring pathstr, bool must_exist) { @@ -298,6 +317,8 @@ AudioFileSource::set_state (const XMLNode& node) } + fix_writable_flags (); + if ((prop = node.property (X_("channel"))) != 0) { _channel = atoi (prop->value()); } else { @@ -324,7 +345,7 @@ AudioFileSource::mark_for_remove () // This operation is not allowed for sources for destructive tracks or embedded files. // Fortunately mark_for_remove() is never called for embedded files. This function // must be fixed if that ever happens. - if (_flags & Destructive) { + if (!_session.writable() || (_flags & Destructive)) { return; } @@ -638,6 +659,8 @@ AudioFileSource::set_allow_remove_if_empty (bool yn) } else { _flags = Flag (_flags & ~RemovableIfEmpty); } + + fix_writable_flags (); } int diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 537086bc9e..0382899b7a 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -117,6 +117,14 @@ Session::first_stage_init (string fullpath, string snapshot_name) _path += '/'; } + if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) { + cerr << "Session non-writable based on " << _path << endl; + _writable = false; + } else { + cerr << "Session writable based on " << _path << endl; + _writable = true; + } + set_history_depth (Config->get_history_depth()); @@ -656,7 +664,7 @@ Session::save_state (string snapshot_name, bool pending) string xml_path; string bak_path; - if (_state_of_the_state & CannotSave) { + if (!_writable || (_state_of_the_state & CannotSave)) { return 1; } @@ -790,6 +798,15 @@ Session::load_state (string snapshot_name) set_dirty(); + /* writable() really reflects the whole folder, but if for any + reason the session state file can't be written to, still + make us unwritable. + */ + + if (::access (xmlpath.c_str(), W_OK) != 0) { + _writable = false; + } + if (!state_tree->read (xmlpath)) { error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg; delete state_tree; @@ -3096,7 +3113,9 @@ Session::controllable_by_id (const PBD::ID& id) void Session::add_instant_xml (XMLNode& node, const std::string& dir) { - Stateful::add_instant_xml (node, dir); + if (_writable) { + Stateful::add_instant_xml (node, dir); + } Config->add_instant_xml (node, get_user_ardour_path()); } @@ -3107,6 +3126,10 @@ Session::save_history (string snapshot_name) string xml_path; string bak_path; + if (!_writable) { + return 0; + } + if (snapshot_name.empty()) { snapshot_name = _current_snapshot_name; } diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 74be7def1d..52989edeff 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -166,6 +166,10 @@ Track::can_record() void Track::set_record_enable (bool yn, void *src) { + if (!_session.writable()) { + return; + } + if (_freeze_record.state == Frozen) { return; } |