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"
34 using namespace ARDOUR
;
37 LocationImportHandler::LocationImportHandler (XMLTree
const & source
, Session
& session
) :
38 ElementImportHandler (source
, session
)
40 XMLNode
const *root
= source
.root();
41 XMLNode
const * location_node
;
43 if (!(location_node
= root
->child ("Locations"))) {
44 throw failed_constructor();
47 // Construct importable locations
48 XMLNodeList
const & locations
= location_node
->children();
49 for (XMLNodeList::const_iterator it
= locations
.begin(); it
!= locations
.end(); ++it
) {
51 elements
.push_back (ElementPtr ( new LocationImporter (source
, session
, *this, **it
)));
52 } catch (failed_constructor err
) {
59 LocationImportHandler::get_info () const
61 return _("Locations");
64 /*** LocationImporter ***/
65 LocationImporter::LocationImporter (XMLTree
const & source
, Session
& session
, LocationImportHandler
& handler
, XMLNode
const & node
) :
66 ElementImporter (source
, session
),
73 XMLPropertyList props
= xml_location
.properties();
75 for (XMLPropertyIterator it
= props
.begin(); it
!= props
.end(); ++it
) {
76 string prop
= (*it
)->name();
77 if (!prop
.compare ("id") || !prop
.compare ("flags") || !prop
.compare ("locked")) {
79 } else if (!prop
.compare ("start") || !prop
.compare ("end")) {
80 // Sample rate conversion
81 (*it
)->set_value (rate_convert_samples ((*it
)->value()));
82 } else if (!prop
.compare ("name")) {
83 // rename region if necessary
84 name
= (*it
)->value();
87 std::cerr
<< string_compose (X_("LocationImporter did not recognise XML-property \"%1\""), prop
) << endmsg
;
92 error
<< X_("LocationImporter did not find necessary XML-property \"name\"") << endmsg
;
93 throw failed_constructor();
97 LocationImporter::~LocationImporter ()
105 LocationImporter::get_info () const
107 nframes_t start
, end
;
108 Timecode::Time start_time
, end_time
;
110 // Get sample positions
111 std::istringstream
iss_start (xml_location
.property ("start")->value());
113 std::istringstream
iss_end (xml_location
.property ("end")->value());
116 // Convert to timecode
117 session
.sample_to_timecode (start
, start_time
, true, false);
118 session
.sample_to_timecode (end
, end_time
, true, false);
121 std::ostringstream oss
;
123 oss
<< _("Location: ") << timecode_to_string (start_time
);
125 oss
<< _("Range\nstart: ") << timecode_to_string (start_time
) <<
126 _("\nend: ") << timecode_to_string (end_time
);
133 LocationImporter::_prepare_move ()
136 Location
const original (xml_location
);
137 location
= new Location (original
); // Updates id
138 } catch (failed_constructor
& err
) {
139 throw std::runtime_error (X_("Error in session file!"));
143 std::pair
<bool, string
> rename_pair
;
145 if (location
->is_auto_punch()) {
146 rename_pair
= *Rename (_("The location is the Punch range. It will be imported as a normal range.\nYou may rename the imported location:"), name
);
147 if (!rename_pair
.first
) {
151 name
= rename_pair
.second
;
152 location
->set_auto_punch (false, this);
153 location
->set_is_range_marker (true, this);
156 if (location
->is_auto_loop()) {
157 rename_pair
= *Rename (_("The location is a Loop range. It will be imported as a normal range.\nYou may rename the imported location:"), name
);
158 if (!rename_pair
.first
) { return false; }
160 location
->set_auto_loop (false, this);
161 location
->set_is_range_marker (true, this);
164 // duplicate name checking
165 Locations::LocationList
const & locations(session
.locations()->list());
166 for (Locations::LocationList::const_iterator it
= locations
.begin(); it
!= locations
.end(); ++it
) {
167 if (!((*it
)->name().compare (location
->name())) || !handler
.check_name (location
->name())) {
168 rename_pair
= *Rename (_("A location with that name already exists.\nYou may rename the imported location:"), name
);
169 if (!rename_pair
.first
) { return false; }
170 name
= rename_pair
.second
;
174 location
->set_name (name
);
180 LocationImporter::_cancel_move ()
187 LocationImporter::_move ()
189 session
.locations()->add (location
);