2 Copyright (C) 2008 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <ardour/location_importer.h>
26 #include <ardour/session.h>
27 #include <pbd/convert.h>
28 #include <pbd/failed_constructor.h>
33 using namespace ARDOUR;
36 LocationImportHandler::LocationImportHandler (XMLTree const & source, Session & session) :
37 ElementImportHandler (source, session)
39 XMLNode const *root = source.root();
40 XMLNode const * location_node;
42 if (!(location_node = root->child ("Locations"))) {
43 throw failed_constructor();
46 // Construct importable locations
47 XMLNodeList const & locations = location_node->children();
48 for (XMLNodeList::const_iterator it = locations.begin(); it != locations.end(); it++) {
50 elements.push_back (ElementPtr ( new LocationImporter (source, session, *this, **it)));
51 } catch (failed_constructor err) {
58 LocationImportHandler::get_info () const
60 return _("Locations");
63 /*** LocationImporter ***/
64 LocationImporter::LocationImporter (XMLTree const & source, Session & session, LocationImportHandler & handler, XMLNode const & node) :
65 ElementImporter (source, session),
72 XMLPropertyList props = xml_location.properties();
74 for (XMLPropertyIterator it = props.begin(); it != props.end(); ++it) {
75 string prop = (*it)->name();
76 if (!prop.compare ("id") || !prop.compare ("flags") || !prop.compare ("locked")) {
78 } else if (!prop.compare ("start") || !prop.compare ("end")) {
79 // Sample rate conversion
80 (*it)->set_value (rate_convert_samples ((*it)->value()));
81 } else if (!prop.compare ("name")) {
82 // rename region if necessary
83 name = (*it)->value();
86 std::cerr << string_compose (X_("LocationImporter did not recognise XML-property \"%1\""), prop) << endmsg;
91 error << X_("LocationImporter did not find necessary XML-property \"name\"") << endmsg;
92 throw failed_constructor();
96 LocationImporter::~LocationImporter ()
98 if (!queued && location) {
104 LocationImporter::get_info () const
106 nframes_t start, end;
107 SMPTE::Time start_time, end_time;
109 // Get sample positions
110 std::istringstream iss_start (xml_location.property ("start")->value());
112 std::istringstream iss_end (xml_location.property ("end")->value());
116 session.sample_to_smpte (start, start_time, true, false);
117 session.sample_to_smpte (end, end_time, true, false);
120 std::ostringstream oss;
122 oss << _("Location: ") << smpte_to_string (start_time);
124 oss << _("Range\nstart: ") << smpte_to_string (start_time) <<
125 _("\nend: ") << smpte_to_string (end_time);
132 LocationImporter::prepare_move ()
135 Location const original (xml_location);
136 location = new Location (original); // Updates id
137 } catch (failed_constructor& err) {
138 throw std::runtime_error (X_("Error in session file!"));
142 std::pair<bool, string> rename_pair;
144 if (location->is_auto_punch()) {
145 rename_pair = Rename (_("The location is the Punch range. It will be imported as a normal range.\nYou may rename the imported location:"), name);
146 if (!rename_pair.first) {
150 name = rename_pair.second;
151 location->set_auto_punch (false, this);
152 location->set_is_range_marker (true, this);
155 if (location->is_auto_loop()) {
156 rename_pair = Rename (_("The location is a Loop range. It will be imported as a normal range.\nYou may rename the imported location:"), name);
157 if (!rename_pair.first) { return false; }
159 location->set_auto_loop (false, this);
160 location->set_is_range_marker (true, this);
163 // duplicate name checking
164 Locations::LocationList const & locations(session.locations()->list());
165 for (Locations::LocationList::const_iterator it = locations.begin(); it != locations.end(); ++it) {
166 if (!((*it)->name().compare (location->name())) || !handler.check_name (location->name())) {
167 rename_pair = Rename (_("A location with that name already exists.\nYou may rename the imported location:"), name);
168 if (!rename_pair.first) { return false; }
169 name = rename_pair.second;
173 location->set_name (name);
179 LocationImporter::cancel_move ()
189 LocationImporter::move ()
194 session.locations()->add (location);