Fix log-scale rangesteps and log-control numeric spinboxes
[ardour.git] / libs / ardour / session_state.cc
index 0110b8e156f66819aa5e10b4665e1f549146aacd..6eb06d8c356abb6ba7edc3a76f6cec65d639c54f 100644 (file)
@@ -85,7 +85,6 @@
 #include "ardour/automation_control.h"
 #include "ardour/boost_debug.h"
 #include "ardour/butler.h"
-#include "ardour/controllable_descriptor.h"
 #include "ardour/control_protocol_manager.h"
 #include "ardour/directory_names.h"
 #include "ardour/disk_reader.h"
@@ -183,7 +182,6 @@ Session::pre_engine_init (string fullpath)
        g_atomic_int_set (&_capture_load, 100);
        set_next_event ();
        _all_route_group->set_active (true, this);
-       interpolation.add_channel ();
 
        if (config.get_use_video_sync()) {
                waiting_for_sync_offset = true;
@@ -751,6 +749,8 @@ Session::remove_state (string snapshot_name)
                error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
                                xml_path, g_strerror (errno)) << endmsg;
        }
+
+       StateSaved (snapshot_name); /* EMIT SIGNAL */
 }
 
 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
@@ -875,6 +875,32 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                }
        }
 
+       //Mixbus auto-backup mechanism
+       if(Profile->get_mixbus()) {
+               if (pending) {  //"pending" save means it's a backup, or some other non-user-initiated save;  a good time to make a backup
+                       // make a serialized safety backup
+                       // (will make one periodically but only one per hour is left on disk)
+                       // these backup files go into a separated folder
+                       char timebuf[128];
+                       time_t n;
+                       struct tm local_time;
+                       time (&n);
+                       localtime_r (&n, &local_time);
+                       strftime (timebuf, sizeof(timebuf), "%y-%m-%d.%H", &local_time);
+                       std::string save_path(session_directory().backup_path());
+                       save_path += G_DIR_SEPARATOR;
+                       save_path += legalize_for_path(_current_snapshot_name);
+                       save_path += "-";
+                       save_path += timebuf;
+                       save_path += statefile_suffix;
+                       if ( !tree.write (save_path) )
+                                       error << string_compose(_("Could not save backup file at path \"%1\" (%2)"),
+                                                       save_path, g_strerror (errno)) << endmsg;
+               }
+
+               StateSaved (snapshot_name); /* EMIT SIGNAL */
+       }
+
        if (!pending && !for_archive) {
 
                save_history (snapshot_name);
@@ -3731,143 +3757,6 @@ Session::automation_control_by_id (const PBD::ID& id)
        return boost::dynamic_pointer_cast<AutomationControl> (controllable_by_id (id));
 }
 
-boost::shared_ptr<Controllable>
-Session::controllable_by_descriptor (const ControllableDescriptor& desc)
-{
-       boost::shared_ptr<Controllable> c;
-       boost::shared_ptr<Stripable> s;
-       boost::shared_ptr<Route> r;
-
-       switch (desc.top_level_type()) {
-       case ControllableDescriptor::NamedRoute:
-       {
-               std::string str = desc.top_level_name();
-
-               if (str == "Master" || str == "master") {
-                       s = _master_out;
-               } else if (str == "control" || str == "listen" || str == "monitor" || str == "Monitor") {
-                       s = _monitor_out;
-               } else if (str == "auditioner") {
-                       s = auditioner;
-               } else {
-                       s = route_by_name (desc.top_level_name());
-               }
-
-               break;
-       }
-
-       case ControllableDescriptor::PresentationOrderRoute:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Route);
-               break;
-
-       case ControllableDescriptor::PresentationOrderTrack:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Track);
-               break;
-
-       case ControllableDescriptor::PresentationOrderBus:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::Bus);
-               break;
-
-       case ControllableDescriptor::PresentationOrderVCA:
-               s = get_remote_nth_stripable (desc.presentation_order(), PresentationInfo::VCA);
-               break;
-
-       case ControllableDescriptor::SelectionCount:
-               s = route_by_selected_count (desc.selection_id());
-               break;
-       }
-
-       if (!s) {
-               return c;
-       }
-
-       r = boost::dynamic_pointer_cast<Route> (s);
-
-       switch (desc.subtype()) {
-       case ControllableDescriptor::Gain:
-               c = s->gain_control ();
-               break;
-
-       case ControllableDescriptor::Trim:
-               c = s->trim_control ();
-               break;
-
-       case ControllableDescriptor::Solo:
-               c = s->solo_control();
-               break;
-
-       case ControllableDescriptor::Mute:
-               c = s->mute_control();
-               break;
-
-       case ControllableDescriptor::Recenable:
-               c = s->rec_enable_control ();
-               break;
-
-       case ControllableDescriptor::PanDirection:
-               c = s->pan_azimuth_control();
-               break;
-
-       case ControllableDescriptor::PanWidth:
-               c = s->pan_width_control();
-               break;
-
-       case ControllableDescriptor::PanElevation:
-               c = s->pan_elevation_control();
-               break;
-
-       case ControllableDescriptor::Balance:
-               /* XXX simple pan control */
-               break;
-
-       case ControllableDescriptor::PluginParameter:
-       {
-               uint32_t plugin = desc.target (0);
-               uint32_t parameter_index = desc.target (1);
-
-               /* revert to zero based counting */
-
-               if (plugin > 0) {
-                       --plugin;
-               }
-
-               if (parameter_index > 0) {
-                       --parameter_index;
-               }
-
-               if (!r) {
-                       return c;
-               }
-
-               boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
-
-               if (p) {
-                       c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
-                               p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
-               }
-               break;
-       }
-
-       case ControllableDescriptor::SendGain: {
-               uint32_t send = desc.target (0);
-               if (send > 0) {
-                       --send;
-               }
-               if (!r) {
-                       return c;
-               }
-               c = r->send_level_controllable (send);
-               break;
-       }
-
-       default:
-               /* relax and return a null pointer */
-               break;
-       }
-
-       return c;
-}
-
 void
 Session::add_instant_xml (XMLNode& node, bool write_to_config)
 {
@@ -3974,7 +3863,6 @@ Session::restore_history (string snapshot_name)
        for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); ++it) {
 
                XMLNode *t = *it;
-               UndoTransaction* ut = new UndoTransaction ();
 
                std::string name;
                int64_t tv_sec;
@@ -3985,6 +3873,7 @@ Session::restore_history (string snapshot_name)
                        continue;
                }
 
+               UndoTransaction* ut = new UndoTransaction ();
                ut->set_name (name);
 
                struct timeval tv;