From 8c4ce1e2ce35571aed5a686671431fdfffae7f8c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 13 Oct 2009 20:43:28 +0000 Subject: [PATCH] writable session patch, forward ported from 2.X git-svn-id: svn://localhost/ardour2/branches/3.0@5770 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/actions.cc | 1 + gtk2_ardour/actions.h | 1 + gtk2_ardour/ardour_ui.cc | 12 +--- gtk2_ardour/ardour_ui_dialogs.cc | 1 + gtk2_ardour/ardour_ui_ed.cc | 13 ++++- gtk2_ardour/editor_actions.cc | 8 ++- gtk2_ardour/mixer_strip.cc | 1 + gtk2_ardour/route_time_axis.cc | 1 + gtk2_ardour/route_ui.cc | 2 +- libs/ardour/ardour/file_source.h | 2 +- libs/ardour/ardour/session.h | 4 +- libs/ardour/ardour/source.h | 3 +- libs/ardour/audio_diskstream.cc | 2 +- libs/ardour/file_source.cc | 2 +- libs/ardour/session_state.cc | 99 ++++++++++++++++++++------------ libs/ardour/source.cc | 12 ++++ libs/ardour/track.cc | 4 ++ 17 files changed, 108 insertions(+), 60 deletions(-) diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc index 5e9c067476..19a33ef177 100644 --- a/gtk2_ardour/actions.cc +++ b/gtk2_ardour/actions.cc @@ -47,6 +47,7 @@ using namespace PBD; using namespace ARDOUR; vector > ActionManager::session_sensitive_actions; +vector > ActionManager::write_sensitive_actions; vector > ActionManager::region_list_selection_sensitive_actions; vector > ActionManager::plugin_selection_sensitive_actions; vector > ActionManager::region_selection_sensitive_actions; diff --git a/gtk2_ardour/actions.h b/gtk2_ardour/actions.h index 3a20f4d542..35331fdac2 100644 --- a/gtk2_ardour/actions.h +++ b/gtk2_ardour/actions.h @@ -42,6 +42,7 @@ class ActionManager static void init (); static std::vector > session_sensitive_actions; + static std::vector > write_sensitive_actions; static std::vector > region_list_selection_sensitive_actions; static std::vector > plugin_selection_sensitive_actions; diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index ea89b062c8..45f6191dd3 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -577,7 +577,7 @@ ARDOUR_UI::update_autosave () { ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave)); - if (session->dirty()) { + if (session && session->dirty()) { if (_autosave_connection.connected()) { _autosave_connection.disconnect(); } @@ -2397,16 +2397,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 91ff10d473..e816c3ce91 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -57,6 +57,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 b827625db2..d76ff43791 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_("TransportOptions"), _("Options")); ActionManager::register_action (main_actions, X_("Help"), _("Help")); @@ -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); #ifdef WITH_CMT @@ -132,6 +132,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); @@ -153,7 +154,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::write_sensitive_actions.push_back (act); ActionManager::session_sensitive_actions.push_back (act); /* JACK actions for controlling ... JACK */ @@ -226,6 +230,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); @@ -277,8 +282,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 db99e3529e..0418942164 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -847,10 +847,14 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Import"), mem_fun (*this, &Editor::external_audio_dialog)); ActionManager::session_sensitive_actions.push_back (act); + 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::register_action (editor_actions, X_("importFromSession"), _("Import From Session"), mem_fun(*this, &Editor::session_import_dialog)); + ActionManager::write_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, X_("importFromSession"), _("Import From Session"), mem_fun(*this, &Editor::session_import_dialog)); + ActionManager::write_sensitive_actions.push_back (act); ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformsWhileRecording"), _("Show Waveforms While Recording"), mem_fun (*this, &Editor::toggle_waveforms_while_recording)); diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 5f7a89d90a..4b3cb3649f 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -369,6 +369,7 @@ MixerStrip::set_route (boost::shared_ptr rt) connections.push_back (at->FreezeChange.connect (mem_fun(*this, &MixerStrip::map_frozen))); button_table.attach (*rec_enable_button, 0, 2, 2, 3); + rec_enable_button->set_sensitive (_session.writable()); rec_enable_button->show(); } else if (!is_track()) { diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 68ca7008c7..9a3a6a3124 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -188,6 +188,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 9a64ca8aa3..703857bc6b 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -190,7 +190,7 @@ RouteUI::set_route (boost::shared_ptr rp) connections.push_back (_route->listen_changed.connect (mem_fun(*this, &RouteUI::listen_changed))); connections.push_back (_route->solo_isolated_changed.connect (mem_fun(*this, &RouteUI::solo_changed))); - if (is_track()) { + if (_session.writable() && is_track()) { boost::shared_ptr t = boost::dynamic_pointer_cast(_route); connections.push_back (t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed))); diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h index fdf7473c63..82a54094ef 100644 --- a/libs/ardour/ardour/file_source.h +++ b/libs/ardour/ardour/file_source.h @@ -68,7 +68,7 @@ protected: virtual int move_dependents_to_trash() { return 0; } bool removable () const; - + Glib::ustring _path; Glib::ustring _take_id; bool _file_is_new; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 7da21274e1..cdf6547674 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -248,7 +248,8 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable std::string raid_path () 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; } @@ -1041,6 +1042,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable float _meter_falloff; bool _non_soloed_outs_muted; uint32_t _listen_cnt; + bool _writable; void set_worst_io_latencies (); void set_worst_io_latencies_x (IOChange, void *) { diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index d6c68edf90..a61af84ac8 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -79,7 +79,7 @@ class Source : public SessionObject, public boost::noncopyable int set_state (const XMLNode&); bool destructive() const { return (_flags & Destructive); } - bool writable () const { return _flags & Writable; } + bool writable () const { return (_flags & Writable); } virtual bool set_destructive (bool /*yn*/) { return false; } virtual bool length_mutable() const { return false; } @@ -128,6 +128,7 @@ class Source : public SessionObject, public boost::noncopyable private: uint32_t _in_use; + void fix_writable_flags (); }; } diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 5c00f10f48..04f4173e4d 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -2065,7 +2065,7 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/) boost::shared_ptr c = channels.reader(); uint32_t n; - if (!recordable()) { + if (!_session.writable() || !recordable()) { return; } diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc index dc582a36ee..a8119170de 100644 --- a/libs/ardour/file_source.cc +++ b/libs/ardour/file_source.cc @@ -67,7 +67,7 @@ FileSource::FileSource (Session& session, DataType type, FileSource::FileSource (Session& session, const XMLNode& node, bool /*must_exist*/) : Source(session, node) - , _file_is_new(false) + , _file_is_new (false) { _path = _name; _is_embedded = (_path.find(PATH_SEP) != string::npos); diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 32a4a50cb4..771e3b2bc6 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -63,52 +63,52 @@ #include "pbd/search_path.h" #include "pbd/stacktrace.h" +#include "ardour/audio_diskstream.h" +#include "ardour/audio_track.h" #include "ardour/audioengine.h" -#include "ardour/configuration.h" -#include "ardour/session.h" -#include "ardour/session_directory.h" -#include "ardour/session_utils.h" -#include "ardour/session_state_utils.h" -#include "ardour/session_metadata.h" +#include "ardour/audiofilesource.h" +#include "ardour/audioplaylist.h" +#include "ardour/audioregion.h" +#include "ardour/auditioner.h" #include "ardour/buffer.h" -#include "ardour/audio_diskstream.h" +#include "ardour/configuration.h" +#include "ardour/control_protocol_manager.h" +#include "ardour/crossfade.h" +#include "ardour/cycle_timer.h" +#include "ardour/directory_names.h" +#include "ardour/filename_extensions.h" +#include "ardour/io_processor.h" +#include "ardour/location.h" #include "ardour/midi_diskstream.h" -#include "ardour/utils.h" -#include "ardour/audioplaylist.h" +#include "ardour/midi_patch_manager.h" #include "ardour/midi_playlist.h" -#include "ardour/smf_source.h" -#include "ardour/audiofilesource.h" -#include "ardour/silentfilesource.h" -#include "ardour/sndfilesource.h" +#include "ardour/midi_region.h" #include "ardour/midi_source.h" -#include "ardour/sndfile_helpers.h" -#include "ardour/auditioner.h" -#include "ardour/io_processor.h" -#include "ardour/send.h" -#include "ardour/processor.h" -#include "ardour/user_bundle.h" -#include "ardour/slave.h" -#include "ardour/tempo.h" -#include "ardour/audio_track.h" #include "ardour/midi_track.h" -#include "ardour/midi_patch_manager.h" -#include "ardour/cycle_timer.h" -#include "ardour/utils.h" #include "ardour/named_selection.h" -#include "ardour/version.h" -#include "ardour/location.h" -#include "ardour/audioregion.h" -#include "ardour/midi_region.h" -#include "ardour/crossfade.h" -#include "ardour/control_protocol_manager.h" +#include "ardour/playlist_factory.h" +#include "ardour/processor.h" #include "ardour/region_factory.h" +#include "ardour/route_group.h" +#include "ardour/send.h" +#include "ardour/session.h" +#include "ardour/session_directory.h" +#include "ardour/session_metadata.h" +#include "ardour/session_state_utils.h" +#include "ardour/session_utils.h" +#include "ardour/silentfilesource.h" +#include "ardour/slave.h" +#include "ardour/smf_source.h" +#include "ardour/sndfile_helpers.h" +#include "ardour/sndfilesource.h" #include "ardour/source_factory.h" -#include "ardour/playlist_factory.h" -#include "ardour/filename_extensions.h" -#include "ardour/directory_names.h" #include "ardour/template_utils.h" +#include "ardour/tempo.h" #include "ardour/ticker.h" -#include "ardour/route_group.h" +#include "ardour/user_bundle.h" +#include "ardour/utils.h" +#include "ardour/utils.h" +#include "ardour/version.h" #include "control_protocol/control_protocol.h" @@ -140,6 +140,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; + } + /* these two are just provisional settings. set_state() will likely override them. */ @@ -665,7 +673,7 @@ Session::save_state (string snapshot_name, bool pending) XMLTree tree; sys::path xml_path(_session_dir->root_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.to_string().c_str(), W_OK) != 0) { + _writable = false; + } + if (!state_tree->read (xmlpath.to_string())) { error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg; delete state_tree; @@ -2795,7 +2812,10 @@ Session::controllable_by_id (const PBD::ID& id) void Session::add_instant_xml (XMLNode& node, bool write_to_config) { - Stateful::add_instant_xml (node, _path); + if (_writable) { + Stateful::add_instant_xml (node, _path); + } + if (write_to_config) { Config->add_instant_xml (node); } @@ -2812,6 +2832,10 @@ Session::save_history (string snapshot_name) { XMLTree tree; + if (!_writable) { + return 0; + } + if (snapshot_name.empty()) { snapshot_name = _current_snapshot_name; } @@ -2833,7 +2857,6 @@ Session::save_history (string snapshot_name) } } - if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) { return 0; } diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc index b052a5b1fa..d7002f2fe1 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -55,6 +55,7 @@ Source::Source (Session& s, DataType type, const string& name, Flag flags) _analysed = false; _timestamp = 0; _in_use = 0; + fix_writable_flags (); } Source::Source (Session& s, const XMLNode& node) @@ -70,6 +71,8 @@ Source::Source (Session& s, const XMLNode& node) if (set_state (node) || _type == DataType::NIL) { throw failed_constructor(); } + + fix_writable_flags (); } Source::~Source () @@ -77,6 +80,15 @@ Source::~Source () notify_callbacks (); } + +void +Source::fix_writable_flags () +{ + if (!_session.writable()) { + _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); + } +} + XMLNode& Source::get_state () { diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 23da42f86e..62639c8d3e 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -170,6 +170,10 @@ Track::can_record() void Track::set_record_enable (bool yn, void *src) { + if (!_session.writable()) { + return; + } + if (_freeze_record.state == Frozen) { return; } -- 2.30.2