fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / audio_region_importer.cc
index ab8261a369cc950d16806a2e1fe221bf24b3a783..8fc5c53d6d4ecc6704db1e074aefd68c0fa4d907 100644 (file)
 
 */
 
-#include <ardour/audio_region_importer.h>
+#include "ardour/audio_region_importer.h"
 
 #include <sstream>
 
-#include <pbd/failed_constructor.h>
-#include <pbd/compose.h>
-#include <pbd/error.h>
+#include <glibmm/miscutils.h>
 
-#include <ardour/session.h>
-#include <ardour/region.h>
-#include <ardour/source_factory.h>
-#include <ardour/region_factory.h>
-#include <ardour/session_directory.h>
+#include "pbd/failed_constructor.h"
+#include "pbd/compose.h"
+#include "pbd/error.h"
 
-#include "i18n.h"
+#include "ardour/session.h"
+#include "ardour/region.h"
+#include "ardour/region_factory.h"
+#include "ardour/session_directory.h"
 
+#include "pbd/i18n.h"
+
+using namespace std;
 using namespace PBD;
 using namespace ARDOUR;
 
@@ -43,11 +45,11 @@ AudioRegionImportHandler::AudioRegionImportHandler (XMLTree const & source, Sess
 {
        XMLNode const * root = source.root();
        XMLNode const * regions;
-       
+
        if (!(regions = root->child (X_("Regions")))) {
                throw failed_constructor();
        }
-       
+
        create_regions_from_children (*regions, elements);
 }
 
@@ -104,7 +106,7 @@ AudioRegionImportHandler::get_new_id (PBD::ID & old_id) const
 }
 
 /*** AudioRegionImporter ***/
-AudioRegionImporter::AudioRegionImporter (XMLTree const & source, Session & session, AudioRegionImportHandler & handler, XMLNode const & node) : 
+AudioRegionImporter::AudioRegionImporter (XMLTree const & source, Session & session, AudioRegionImportHandler & handler, XMLNode const & node) :
   ElementImporter (source, session),
   xml_region (node),
   handler (handler),
@@ -118,50 +120,52 @@ AudioRegionImporter::AudioRegionImporter (XMLTree const & source, Session & sess
        handler.register_id (old_id, id);
 }
 
+AudioRegionImporter::~AudioRegionImporter ()
+{
+}
+
 string
 AudioRegionImporter::get_info () const
 {
-       nframes_t length, position;
-       SMPTE::Time length_time, position_time;
+       framecnt_t length, position;
+       Timecode::Time length_time, position_time;
        std::ostringstream oss;
-       
+
        // Get sample positions
        std::istringstream iss_length(xml_region.property ("length")->value());
        iss_length >> length;
        std::istringstream iss_position(xml_region.property ("position")->value());
        iss_position >> position;
-       
-       // Convert to smpte
-       session.sample_to_smpte(length, length_time, true, false);
-       session.sample_to_smpte(position, position_time, true, false);
-       
+
+       // Convert to timecode
+       session.sample_to_timecode(length, length_time, true, false);
+       session.sample_to_timecode(position, position_time, true, false);
+
        // return info
        oss << _("Length: ") <<
-         smpte_to_string(length_time) <<
-         _("\nPosition: ") << 
-         smpte_to_string(position_time) <<
+         timecode_to_string(length_time) <<
+         _("\nPosition: ") <<
+         timecode_to_string(position_time) <<
          _("\nChannels: ") <<
          xml_region.property ("channels")->value();
 
-       
+
        return oss.str();
 }
 
 bool
-AudioRegionImporter::prepare_move ()
+AudioRegionImporter::_prepare_move ()
 {
-       queued = true;
        return true;
 }
 
 void
-AudioRegionImporter::cancel_move ()
+AudioRegionImporter::_cancel_move ()
 {
-       queued = false;
 }
 
 void
-AudioRegionImporter::move ()
+AudioRegionImporter::_move ()
 {
        if (!region_prepared) {
                prepare_region();
@@ -169,27 +173,26 @@ AudioRegionImporter::move ()
                        return;
                }
        }
-       
+
        if (broken()) {
                return;
        }
-       
-       session.add_regions (region);
 }
 
 bool
 AudioRegionImporter::parse_xml_region ()
 {
-       XMLPropertyList const & props = xml_region.properties();;
+       XMLPropertyList const & props = xml_region.properties();
        bool id_ok = false;
        bool name_ok = false;
-       
+
        for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
                string prop = (*it)->name();
                if (!prop.compare ("type") || !prop.compare ("stretch") ||
                  !prop.compare ("shift") || !prop.compare ("first_edit") ||
                  !prop.compare ("layer") || !prop.compare ("flags") ||
                  !prop.compare ("scale-gain") || !prop.compare("channels") ||
+                 !prop.compare ("first-edit") ||
                  prop.find ("master-source-") == 0 || prop.find ("source-") == 0) {
                        // All ok
                } else if (!prop.compare ("start") || !prop.compare ("length") ||
@@ -205,24 +208,24 @@ AudioRegionImporter::parse_xml_region ()
                } else if (!prop.compare("name")) {
                        // rename region if necessary
                        name = (*it)->value();
-                       name = session.new_region_name (name);
+                       name = RegionFactory::new_region_name (name);
                        (*it)->set_value (name);
                        name_ok = true;
                } else {
-                       std::cerr << string_compose (X_("AudioRegionImporter (%1): did not recognise XML-property \"%1\""), name, prop) << endmsg;
+                       std::cerr << string_compose (X_("AudioRegionImporter (%1): did not recognise XML-property \"%2\""), name, prop) << endmsg;
                }
        }
-       
+
        if (!id_ok) {
                error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"id\""), name) << endmsg;
                return false;
        }
-       
+
        if (!name_ok) {
                error << X_("AudioRegionImporter: did not find necessary XML-property \"name\"") << endmsg;
                return false;
        }
-       
+
        return true;
 }
 
@@ -231,72 +234,64 @@ AudioRegionImporter::parse_source_xml ()
 {
        uint32_t channels;
        char buf[128];
-       PBD::sys::path source_dir = get_sound_dir (source);
-       PBD::sys::path source_path;
+       std::string source_dir(get_sound_dir (source));
        XMLNode * source_node;
-       XMLProperty *prop;
-       
+       XMLProperty const * prop;
+
        // Get XML for sources
        if (!(source_node = source.root()->child (X_("Sources")))) {
                return false;
        }
        XMLNodeList const & sources = source_node->children();
-       
+
        // Get source for each channel
        if (!(prop = xml_region.property ("channels"))) {
                error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"channels\""), name) << endmsg;
                return false;
        }
-       
-       channels = atoi (prop->value());
+
+       channels = atoi (prop->value().c_str());
        for (uint32_t i = 0; i < channels; ++i) {
                bool source_found = false;
-               
+
                // Get id for source-n
                snprintf (buf, sizeof(buf), X_("source-%d"), i);
                prop = xml_region.property (buf);
                if (!prop) {
-                       error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"%3\""), name, buf) << endmsg;
+                       error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"%2\""), name, buf) << endmsg;
                        return false;
                }
                string source_id = prop->value();
-               
+
                // Get source
-               for (XMLNodeList::const_iterator it = sources.begin(); it != sources.end(); it++) {
+               for (XMLNodeList::const_iterator it = sources.begin(); it != sources.end(); ++it) {
                        prop = (*it)->property ("id");
                        if (prop && !source_id.compare (prop->value())) {
-                               source_path = source_dir;
                                prop = (*it)->property ("name");
                                if (!prop) {
                                        error << string_compose (X_("AudioRegionImporter (%1): source %2 has no \"name\" property"), name, source_id) << endmsg;
                                        return false;
                                }
-                               source_path /= prop->value();
-                               filenames.push_back (source_path.to_string());
-                               
+                               filenames.push_back (Glib::build_filename (source_dir, prop->value()));
                                source_found = true;
                                break;
                        }
                }
-               
+
                if (!source_found) {
                        error << string_compose (X_("AudioRegionImporter (%1): could not find all necessary sources"), name) << endmsg;
                        return false;
                }
        }
-       
+
        return true;
 }
 
-PBD::sys::path
+std::string
 AudioRegionImporter::get_sound_dir (XMLTree const & tree)
 {
-       PBD::sys::path source_dir = tree.filename();
-       source_dir = source_dir.branch_path();
-       SessionDirectory session_dir(source_dir);
-       source_dir = session_dir.sound_path();
-       
-       return source_dir;
+       SessionDirectory session_dir(Glib::path_get_dirname (tree.filename()));
+       return session_dir.sound_path();
 }
 
 void
@@ -305,17 +300,21 @@ AudioRegionImporter::prepare_region ()
        if (region_prepared) {
                return;
        }
-       
+
        SourceList source_list;
        prepare_sources();
-       
+
        // Create source list
        for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
                source_list.push_back (handler.get_source (*it));
        }
-       
+
        // create region and update XML
-       region.push_back (RegionFactory::create (source_list, xml_region));
+       boost::shared_ptr<Region> r = RegionFactory::create (source_list, xml_region);
+       if (session.config.get_glue_new_regions_to_bars_and_beats ()) {
+               r->set_position_lock_style (MusicTime);
+       }
+       region.push_back (r);
        if (*region.begin()) {
                xml_region = (*region.begin())->get_state();
        } else {
@@ -332,30 +331,29 @@ AudioRegionImporter::prepare_sources ()
        if (sources_prepared) {
                return;
        }
-       
-       Session::import_status status;
-       
+
+       status.total = 0;
+       status.replace_existing_source = false;
+       status.done = false;
+       status.cancel = false;
+       status.freeze = false;
+       status.progress = 0.0;
+       status.quality = SrcBest; // TODO other qualities also
+
        // Get sources that still need to be imported
        for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
                if (!handler.check_source (*it)) {
                        status.paths.push_back (*it);
+                       status.total++;
                }
        }
-       
-       // Prepare rest of import struct TODO quality
-       status.replace_existing_source = false;
-       status.done = false;
-       status.cancel = false;
-       status.freeze = false;
-       status.progress = 0.0;
-       status.quality = SrcBest;
-       
+
        // import files
        // TODO: threading & exception handling
-       session.import_audiofiles (status);
-       
+       session.import_files (status);
+
        // Add imported sources to handlers map
-       std::vector<Glib::ustring>::iterator file_it = status.paths.begin();
+       std::vector<string>::iterator file_it = status.paths.begin();
        for (SourceList::iterator source_it = status.sources.begin(); source_it != status.sources.end(); ++source_it) {
                if (*source_it) {
                        handler.add_source(*file_it, *source_it);
@@ -364,10 +362,10 @@ AudioRegionImporter::prepare_sources ()
                        handler.set_errors();
                        set_broken();
                }
-               
+
                ++file_it;
        }
-       
+
        sources_prepared = true;
 }
 
@@ -377,22 +375,22 @@ AudioRegionImporter::add_sources_to_session ()
        if (!sources_prepared) {
                prepare_sources();
        }
-       
+
        if (broken()) {
                return;
        }
-       
+
        for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
                session.add_source (handler.get_source (*it));
        }
 }
 
-XMLNode const & 
+XMLNode const &
 AudioRegionImporter::get_xml ()
 {
        if(!region_prepared) {
                prepare_region();
        }
-       
+
        return xml_region;
 }