summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/actions.cc1
-rw-r--r--gtk2_ardour/actions.h1
-rw-r--r--gtk2_ardour/ardour_ui.cc10
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc1
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc12
-rw-r--r--gtk2_ardour/editor_actions.cc4
-rw-r--r--gtk2_ardour/mixer_strip.cc1
-rw-r--r--gtk2_ardour/route_time_axis.cc1
-rw-r--r--gtk2_ardour/route_ui.cc2
-rw-r--r--libs/ardour/ardour/audiofilesource.h3
-rw-r--r--libs/ardour/ardour/session.h5
-rw-r--r--libs/ardour/audio_diskstream.cc2
-rw-r--r--libs/ardour/audiofilesource.cc25
-rw-r--r--libs/ardour/session_state.cc27
-rw-r--r--libs/ardour/track.cc4
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;
}