first pass on track mode switch; fixes to dangling region refs after capture; destroy region menu item removed; small fix to SConstruct for missing C++ case; playlist selection mechanism modified ; new Selection operation added (Add); handle crashing situation with align style change handling caused by recursion
git-svn-id: svn://localhost/ardour2/trunk@1099 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -703,7 +703,7 @@ config_prefix = '$DESTDIR' + final_config_prefix
|
||||
|
||||
conf = Configure (env)
|
||||
|
||||
have_cxx = conf.TryAction (Action (env['CXX'] + ' --version'))
|
||||
have_cxx = conf.TryAction (Action (str(env['CXX']) + ' --version'))
|
||||
if have_cxx[0] != 1:
|
||||
print "This system has no functional C++ compiler. You cannot build Ardour from source without one."
|
||||
sys.exit (1)
|
||||
|
||||
@@ -1946,7 +1946,7 @@ ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* l
|
||||
_("No audio files were ready for cleanup"),
|
||||
true,
|
||||
Gtk::MESSAGE_INFO,
|
||||
(Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE) );
|
||||
(Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
|
||||
msgd.set_secondary_text (_("If this seems suprising, \n\
|
||||
check for any existing snapshots.\n\
|
||||
These may still include regions that\n\
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "selection.h"
|
||||
#include "audio_streamview.h"
|
||||
#include "time_axis_view.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "utils.h"
|
||||
#include "crossfade_view.h"
|
||||
#include "editing.h"
|
||||
@@ -1695,7 +1696,7 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
|
||||
become selected.
|
||||
*/
|
||||
|
||||
region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
|
||||
// region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
|
||||
|
||||
items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
|
||||
items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
|
||||
@@ -1793,8 +1794,6 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
|
||||
items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Destroy"), mem_fun(*this, &Editor::destroy_clicked_region)));
|
||||
|
||||
/* OK, stick the region submenu at the top of the list, and then add
|
||||
the standard items.
|
||||
@@ -2847,6 +2846,13 @@ Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no
|
||||
}
|
||||
break;
|
||||
|
||||
case Selection::Add:
|
||||
if (!selection->selected (&view)) {
|
||||
selection->add (&view);
|
||||
commit = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Selection::Set:
|
||||
if (selection->selected (&view) && selection->tracks.size() == 1) {
|
||||
/* no commit necessary */
|
||||
@@ -2894,7 +2900,7 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_
|
||||
}
|
||||
|
||||
void
|
||||
Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisView*>& relevant_tracks)
|
||||
Editor::get_relevant_audio_tracks (set<AudioTimeAxisView*>& relevant_tracks)
|
||||
{
|
||||
/* step one: get all selected tracks and all tracks in the relevant edit groups */
|
||||
|
||||
@@ -2923,14 +2929,9 @@ Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisVie
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* no active group, or no group */
|
||||
|
||||
relevant_tracks.insert (&base);
|
||||
relevant_tracks.insert (atv);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2939,14 +2940,10 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
|
||||
{
|
||||
set<AudioTimeAxisView*> relevant_tracks;
|
||||
|
||||
if (!clicked_audio_trackview) {
|
||||
return;
|
||||
}
|
||||
|
||||
get_relevant_audio_tracks (*clicked_audio_trackview, relevant_tracks);
|
||||
get_relevant_audio_tracks (relevant_tracks);
|
||||
|
||||
uint32_t sz = relevant_tracks.size();
|
||||
|
||||
|
||||
for (set<AudioTimeAxisView*>::iterator ati = relevant_tracks.begin(); ati != relevant_tracks.end(); ++ati) {
|
||||
sl (**ati, sz);
|
||||
}
|
||||
@@ -3134,7 +3131,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
|
||||
|
||||
set<AudioTimeAxisView*> relevant_tracks;
|
||||
|
||||
get_relevant_audio_tracks (*clicked_audio_trackview, relevant_tracks);
|
||||
get_relevant_audio_tracks (relevant_tracks);
|
||||
|
||||
for (set<AudioTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) {
|
||||
(*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results);
|
||||
@@ -3209,6 +3206,9 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
|
||||
case Selection::Extend:
|
||||
selection->add (all_equivalent_regions);
|
||||
break;
|
||||
case Selection::Add:
|
||||
selection->add (all_equivalent_regions);
|
||||
break;
|
||||
}
|
||||
|
||||
commit_reversible_command () ;
|
||||
|
||||
@@ -412,7 +412,7 @@ class Editor : public PublicEditor
|
||||
CrossfadeView* clicked_crossfadeview;
|
||||
ControlPoint* clicked_control_point;
|
||||
|
||||
void get_relevant_audio_tracks (AudioTimeAxisView& base, std::set<AudioTimeAxisView*>& relevant_tracks);
|
||||
void get_relevant_audio_tracks (std::set<AudioTimeAxisView*>& relevant_tracks);
|
||||
void mapover_audio_tracks (sigc::slot<void,AudioTimeAxisView&,uint32_t> sl);
|
||||
|
||||
/* functions to be passed to mapover_audio_tracks(), possibly with sigc::bind()-supplied arguments */
|
||||
@@ -814,8 +814,8 @@ class Editor : public PublicEditor
|
||||
|
||||
int ensure_cursor (nframes_t* pos);
|
||||
|
||||
void handle_new_audio_region (boost::shared_ptr<ARDOUR::AudioRegion>);
|
||||
void handle_audio_region_removed (boost::shared_ptr<ARDOUR::AudioRegion>);
|
||||
void handle_new_audio_region (boost::weak_ptr<ARDOUR::AudioRegion>);
|
||||
void handle_audio_region_removed (boost::weak_ptr<ARDOUR::AudioRegion>);
|
||||
void add_audio_region_to_region_display (boost::shared_ptr<ARDOUR::AudioRegion>);
|
||||
void region_hidden (boost::shared_ptr<ARDOUR::Region>);
|
||||
void redisplay_regions ();
|
||||
|
||||
@@ -162,9 +162,9 @@ Editor::remove_clicked_region ()
|
||||
void
|
||||
Editor::destroy_clicked_region ()
|
||||
{
|
||||
int32_t selected = selection->regions.size();
|
||||
uint32_t selected = selection->regions.size();
|
||||
|
||||
if (!session || clicked_regionview == 0 && selected == 0) {
|
||||
if (!session || !selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ Do you really want to destroy %1 ?"),
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected > 0) {
|
||||
if (selected) {
|
||||
list<boost::shared_ptr<Region> > r;
|
||||
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
@@ -199,9 +199,6 @@ Do you really want to destroy %1 ?"),
|
||||
}
|
||||
|
||||
session->destroy_regions (r);
|
||||
|
||||
} else if (clicked_regionview) {
|
||||
session->destroy_region (clicked_regionview->region());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,6 +1272,9 @@ Editor::select_all_in_track (Selection::Operation op)
|
||||
case Selection::Extend:
|
||||
/* not defined yet */
|
||||
break;
|
||||
case Selection::Add:
|
||||
selection->add (touched);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1291,6 +1291,7 @@ Editor::select_all (Selection::Operation op)
|
||||
}
|
||||
begin_reversible_command (_("select all"));
|
||||
switch (op) {
|
||||
case Selection::Add:
|
||||
case Selection::Toggle:
|
||||
selection->add (touched);
|
||||
break;
|
||||
@@ -1348,6 +1349,7 @@ Editor::select_all_within (nframes_t start, nframes_t end, double top, double bo
|
||||
|
||||
begin_reversible_command (_("select all within"));
|
||||
switch (op) {
|
||||
case Selection::Add:
|
||||
case Selection::Toggle:
|
||||
cerr << "toggle\n";
|
||||
selection->add (touched);
|
||||
|
||||
@@ -48,22 +48,27 @@ using namespace Glib;
|
||||
using namespace Editing;
|
||||
|
||||
void
|
||||
Editor::handle_audio_region_removed (boost::shared_ptr<AudioRegion> region)
|
||||
Editor::handle_audio_region_removed (boost::weak_ptr<AudioRegion> wregion)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_audio_region_removed), region));
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_audio_region_removed), wregion));
|
||||
redisplay_regions ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::handle_new_audio_region (boost::shared_ptr<AudioRegion> region)
|
||||
Editor::handle_new_audio_region (boost::weak_ptr<AudioRegion> wregion)
|
||||
{
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_region), region));
|
||||
ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_new_audio_region), wregion));
|
||||
|
||||
/* don't copy region - the one we are being notified
|
||||
about belongs to the session, and so it will
|
||||
never be edited.
|
||||
*/
|
||||
add_audio_region_to_region_display (region);
|
||||
|
||||
boost::shared_ptr<AudioRegion> region (wregion.lock());
|
||||
|
||||
if (region) {
|
||||
add_audio_region_to_region_display (region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -796,6 +796,8 @@ Keyboard::modifier_state_equals (guint state, ModifierMask mask)
|
||||
Selection::Operation
|
||||
Keyboard::selection_type (guint state)
|
||||
{
|
||||
/* note that there is no modifier for "Add" */
|
||||
|
||||
if (modifier_state_equals (state, Shift)) {
|
||||
return Selection::Extend;
|
||||
} else if (modifier_state_equals (state, Control)) {
|
||||
|
||||
@@ -968,11 +968,13 @@ RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect)
|
||||
if (plugin_insert->get_gui() == 0) {
|
||||
|
||||
plugin_ui = new PluginUIWindow (plugin_insert);
|
||||
|
||||
if (_owner_is_mixer) {
|
||||
ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui);
|
||||
} else {
|
||||
ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui);
|
||||
}
|
||||
|
||||
plugin_ui->set_title (generate_redirect_title (plugin_insert));
|
||||
plugin_insert->set_gui (plugin_ui);
|
||||
|
||||
|
||||
@@ -79,23 +79,19 @@ RegionSelection::clear_all()
|
||||
{
|
||||
clear();
|
||||
_bylayer.clear();
|
||||
_current_start = 0;
|
||||
_current_end = 0;
|
||||
}
|
||||
|
||||
bool RegionSelection::contains (RegionView* rv)
|
||||
{
|
||||
if (this->find (rv) != end()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->find (rv) != end();
|
||||
}
|
||||
|
||||
void
|
||||
RegionSelection::add (RegionView* rv, bool dosort)
|
||||
{
|
||||
if (this->find (rv) != end()) {
|
||||
if (contains (rv)) {
|
||||
/* we already have it */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -149,8 +149,6 @@ RegionView::~RegionView ()
|
||||
{
|
||||
in_destructor = true;
|
||||
|
||||
RegionViewGoingAway (this); /* EMIT_SIGNAL */
|
||||
|
||||
for (vector<GhostRegion*>::iterator g = ghosts.begin(); g != ghosts.end(); ++g) {
|
||||
delete *g;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <gtkmm2ext/utils.h>
|
||||
|
||||
#include <ardour/playlist.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/diskstream.h>
|
||||
#include <ardour/insert.h>
|
||||
#include <ardour/ladspa_plugin.h>
|
||||
@@ -182,6 +183,7 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
|
||||
|
||||
if (is_track()) {
|
||||
|
||||
track()->TrackModeChanged.connect (mem_fun(*this, &RouteTimeAxisView::track_mode_changed));
|
||||
track()->FreezeChange.connect (mem_fun(*this, &RouteTimeAxisView::map_frozen));
|
||||
track()->DiskstreamChanged.connect (mem_fun(*this, &RouteTimeAxisView::diskstream_changed));
|
||||
get_diskstream()->SpeedChanged.connect (mem_fun(*this, &RouteTimeAxisView::speed_changed));
|
||||
@@ -276,8 +278,6 @@ RouteTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Grou
|
||||
|
||||
MenuList &items = edit_group_menu.items();
|
||||
|
||||
cerr << "adding edit group " << eg->name() << endl;
|
||||
|
||||
items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &RouteTimeAxisView::set_edit_group_from_menu), eg)));
|
||||
if (_route->edit_group() == eg) {
|
||||
static_cast<RadioMenuItem*>(&items.back())->set_active ();
|
||||
@@ -286,18 +286,10 @@ RouteTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Grou
|
||||
|
||||
void
|
||||
RouteTimeAxisView::set_edit_group_from_menu (RouteGroup *eg)
|
||||
|
||||
{
|
||||
_route->set_edit_group (eg, this);
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::playlist_state_changed (Change ignored)
|
||||
{
|
||||
// ENSURE_GUI_THREAD (bind (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed), ignored));
|
||||
// why are we here ?
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::playlist_changed ()
|
||||
|
||||
@@ -342,13 +334,15 @@ RouteTimeAxisView::playlist_click ()
|
||||
{
|
||||
// always build a new action menu
|
||||
|
||||
if (playlist_action_menu == 0) {
|
||||
playlist_action_menu = new Menu;
|
||||
playlist_action_menu->set_name ("ArdourContextMenu");
|
||||
}
|
||||
|
||||
build_playlist_menu(playlist_action_menu);
|
||||
if (playlist_action_menu != 0) {
|
||||
delete playlist_action_menu;
|
||||
}
|
||||
|
||||
playlist_action_menu = new Menu;
|
||||
playlist_action_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
build_playlist_menu (playlist_action_menu);
|
||||
editor.set_selected_track (*this, Selection::Add);
|
||||
playlist_action_menu->popup (1, 0);
|
||||
}
|
||||
|
||||
@@ -361,6 +355,7 @@ RouteTimeAxisView::automation_click ()
|
||||
*/
|
||||
build_display_menu ();
|
||||
}
|
||||
editor.set_selected_track (*this, Selection::Add);
|
||||
automation_action_menu->popup (1, 0);
|
||||
}
|
||||
|
||||
@@ -443,6 +438,24 @@ RouteTimeAxisView::build_display_menu ()
|
||||
|
||||
get_diskstream()->AlignmentStyleChanged.connect (
|
||||
mem_fun(*this, &RouteTimeAxisView::align_style_changed));
|
||||
|
||||
RadioMenuItem::Group mode_group;
|
||||
items.push_back (RadioMenuElem (mode_group, _("Normal mode"),
|
||||
bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::Normal)));
|
||||
normal_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
|
||||
items.push_back (RadioMenuElem (mode_group, _("Tape mode"),
|
||||
bind (mem_fun (*this, &RouteTimeAxisView::set_track_mode), ARDOUR::Destructive)));
|
||||
destructive_track_mode_item = dynamic_cast<RadioMenuItem*>(&items.back());
|
||||
|
||||
|
||||
switch (track()->mode()) {
|
||||
case ARDOUR::Destructive:
|
||||
destructive_track_mode_item->set_active ();
|
||||
break;
|
||||
case ARDOUR::Normal:
|
||||
normal_track_mode_item->set_active ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
items.push_back (SeparatorElem());
|
||||
@@ -454,6 +467,63 @@ RouteTimeAxisView::build_display_menu ()
|
||||
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
|
||||
}
|
||||
|
||||
static bool __reset_item (RadioMenuItem* item)
|
||||
{
|
||||
cerr << "reset item to true\n";
|
||||
item->set_active ();
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::set_track_mode (TrackMode mode)
|
||||
{
|
||||
RadioMenuItem* item;
|
||||
RadioMenuItem* other_item;
|
||||
|
||||
cerr << "STM, mode = " << mode;
|
||||
|
||||
switch (mode) {
|
||||
case ARDOUR::Normal:
|
||||
item = normal_track_mode_item;
|
||||
other_item = destructive_track_mode_item;
|
||||
break;
|
||||
case ARDOUR::Destructive:
|
||||
item = destructive_track_mode_item;
|
||||
other_item = normal_track_mode_item;
|
||||
break;
|
||||
default:
|
||||
fatal << string_compose (_("programming error: %1 %2"), "illegal track mode in RouteTimeAxisView::set_track_mode", mode) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->get_active () && track()->mode() != mode) {
|
||||
if (track()->set_mode (mode)) {
|
||||
Glib::signal_idle().connect (bind (sigc::ptr_fun (__reset_item), other_item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::track_mode_changed ()
|
||||
{
|
||||
RadioMenuItem* item;
|
||||
|
||||
switch (track()->mode()) {
|
||||
case ARDOUR::Normal:
|
||||
item = normal_track_mode_item;
|
||||
break;
|
||||
case ARDOUR::Destructive:
|
||||
item = destructive_track_mode_item;
|
||||
break;
|
||||
default:
|
||||
fatal << string_compose (_("programming error: %1 %2"), "illegal track mode in RouteTimeAxisView::set_track_mode", track()->mode()) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return;
|
||||
}
|
||||
|
||||
item->set_active ();
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::show_timestretch (nframes_t start, nframes_t end)
|
||||
@@ -700,7 +770,24 @@ RouteTimeAxisView::align_style_changed ()
|
||||
void
|
||||
RouteTimeAxisView::set_align_style (AlignStyle style)
|
||||
{
|
||||
get_diskstream()->set_align_style (style);
|
||||
RadioMenuItem* item;
|
||||
|
||||
switch (style) {
|
||||
case ExistingMaterial:
|
||||
item = align_existing_item;
|
||||
break;
|
||||
case CaptureTime:
|
||||
item = align_capture_item;
|
||||
break;
|
||||
default:
|
||||
fatal << string_compose (_("programming error: %1 %2"), "illegal align style in RouteTimeAxisView::set_align_style", style) << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->get_active()) {
|
||||
get_diskstream()->set_align_style (style);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -772,7 +859,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt)
|
||||
|
||||
if (name.length()) {
|
||||
ds->use_copy_playlist ();
|
||||
pl->set_name (name);
|
||||
ds->playlist()->set_name (name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -799,7 +886,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
|
||||
prompter.set_initial_text (name);
|
||||
prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
|
||||
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
|
||||
|
||||
|
||||
switch (prompter.run ()) {
|
||||
case Gtk::RESPONSE_ACCEPT:
|
||||
prompter.get_result (name);
|
||||
@@ -812,7 +899,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
|
||||
|
||||
if (name.length()) {
|
||||
ds->use_new_playlist ();
|
||||
pl->set_name (name);
|
||||
ds->playlist()->set_name (name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,6 +956,10 @@ RouteTimeAxisView::selection_click (GdkEventButton* ev)
|
||||
case Selection::Extend:
|
||||
/* not defined yet */
|
||||
break;
|
||||
|
||||
case Selection::Add:
|
||||
editor.get_selection().add (*tracks);
|
||||
break;
|
||||
}
|
||||
|
||||
delete tracks;
|
||||
@@ -1114,12 +1205,28 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
|
||||
if (playlist_menu) {
|
||||
delete playlist_menu;
|
||||
}
|
||||
|
||||
playlist_menu = new Menu;
|
||||
playlist_menu->set_name ("ArdourContextMenu");
|
||||
|
||||
playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name())));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
vector<Playlist*> playlists;
|
||||
boost::shared_ptr<Diskstream> ds = get_diskstream();
|
||||
RadioMenuItem::Group playlist_group;
|
||||
|
||||
_session.get_playlists (playlists);
|
||||
|
||||
for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
|
||||
if ((*i)->get_orig_diskstream_id() == ds->id()) {
|
||||
playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), (*i))));
|
||||
|
||||
if (ds->playlist()->id() == (*i)->id()) {
|
||||
static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
|
||||
@@ -1128,8 +1235,20 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists)));
|
||||
playlist_items.push_back (SeparatorElem());
|
||||
playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
|
||||
|
||||
playlist_items.push_back (MenuElem(_("Select from all ..."), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
|
||||
}
|
||||
|
||||
void
|
||||
RouteTimeAxisView::use_playlist (Playlist* pl)
|
||||
{
|
||||
AudioPlaylist* apl = dynamic_cast<AudioPlaylist*> (pl);
|
||||
|
||||
assert (is_track());
|
||||
|
||||
if (apl) {
|
||||
get_diskstream()->use_playlist (apl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -180,7 +180,6 @@ protected:
|
||||
void playlist_click ();
|
||||
void show_playlist_selector ();
|
||||
void playlist_changed ();
|
||||
void playlist_state_changed (ARDOUR::Change);
|
||||
void playlist_modified ();
|
||||
|
||||
void rename_current_playlist ();
|
||||
@@ -224,12 +223,19 @@ protected:
|
||||
Gtk::Menu edit_group_menu;
|
||||
Gtk::RadioMenuItem* align_existing_item;
|
||||
Gtk::RadioMenuItem* align_capture_item;
|
||||
Gtk::RadioMenuItem* normal_track_mode_item;
|
||||
Gtk::RadioMenuItem* destructive_track_mode_item;
|
||||
Gtk::Menu* playlist_menu;
|
||||
Gtk::Menu* playlist_action_menu;
|
||||
Gtk::MenuItem* playlist_item;
|
||||
|
||||
void use_playlist (ARDOUR::Playlist*);
|
||||
|
||||
ArdourCanvas::SimpleRect* timestretch_rect;
|
||||
|
||||
|
||||
void set_track_mode (ARDOUR::TrackMode);
|
||||
void track_mode_changed ();
|
||||
|
||||
list<RedirectAutomationInfo*> redirect_automation;
|
||||
vector<RedirectAutomationLine*> redirect_automation_curves;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ class Selection : public sigc::trackable
|
||||
|
||||
enum Operation {
|
||||
Set,
|
||||
Add,
|
||||
Toggle,
|
||||
Extend
|
||||
};
|
||||
|
||||
@@ -475,12 +475,14 @@ TimeAxisView::popup_display_menu (guint32 when)
|
||||
if (display_menu == 0) {
|
||||
build_display_menu ();
|
||||
}
|
||||
editor.set_selected_track (*this, Selection::Add);
|
||||
display_menu->popup (1, when);
|
||||
}
|
||||
|
||||
gint
|
||||
TimeAxisView::size_click (GdkEventButton *ev)
|
||||
{
|
||||
editor.set_selected_track (*this, Selection::Add);
|
||||
popup_size_menu (ev->time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
|
||||
if (focus) {
|
||||
if (GTK_IS_ENTRY(focus)) {
|
||||
special_handling_of_unmodified_accelerators = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This exists to allow us to override the way GTK handles
|
||||
|
||||
@@ -274,7 +274,6 @@ if env['NLS']:
|
||||
|
||||
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libardour))
|
||||
|
||||
env.AlwaysBuild ('version.cc')
|
||||
env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], 'SConscript'))
|
||||
|
||||
env.Alias('tarball', env.Distribute (env['DISTTREE'],
|
||||
|
||||
@@ -77,6 +77,7 @@ class AudioDiskstream : public Diskstream
|
||||
}
|
||||
|
||||
void set_record_enabled (bool yn);
|
||||
int set_destructive (bool yn);
|
||||
|
||||
float peak_power(uint32_t n=0) {
|
||||
float x = channels[n].peak_power;
|
||||
@@ -251,6 +252,8 @@ class AudioDiskstream : public Diskstream
|
||||
|
||||
typedef vector<ChannelInfo> ChannelList;
|
||||
ChannelList channels;
|
||||
|
||||
bool can_become_destructive () const;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -37,6 +37,8 @@ class AudioTrack : public Track
|
||||
AudioTrack (Session&, const XMLNode&);
|
||||
~AudioTrack ();
|
||||
|
||||
int set_mode (TrackMode m);
|
||||
|
||||
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||
nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
|
||||
|
||||
|
||||
@@ -136,6 +136,8 @@ class AudioRegion : public Region
|
||||
void resume_fade_in ();
|
||||
void resume_fade_out ();
|
||||
|
||||
void set_playlist (Playlist *);
|
||||
|
||||
private:
|
||||
friend class RegionFactory;
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class IO;
|
||||
virtual void set_record_enabled (bool yn) = 0;
|
||||
|
||||
bool destructive() const { return _flags & Destructive; }
|
||||
virtual void set_destructive (bool yn);
|
||||
virtual int set_destructive (bool yn) { return -1; }
|
||||
|
||||
bool hidden() const { return _flags & Hidden; }
|
||||
bool recordable() const { return _flags & Recordable; }
|
||||
@@ -138,6 +138,8 @@ class IO;
|
||||
|
||||
void handle_input_change (IOChange, void *src);
|
||||
|
||||
void remove_region_from_last_capture (boost::weak_ptr<Region> wregion);
|
||||
|
||||
sigc::signal<void> RecordEnableChanged;
|
||||
sigc::signal<void> SpeedChanged;
|
||||
sigc::signal<void> ReverseChanged;
|
||||
@@ -224,6 +226,7 @@ class IO;
|
||||
virtual bool realtime_set_speed (double, bool global_change);
|
||||
|
||||
std::list<boost::shared_ptr<Region> > _last_capture_regions;
|
||||
|
||||
virtual int use_pending_capture_data (XMLNode& node) = 0;
|
||||
|
||||
virtual void get_input_sources () = 0;
|
||||
|
||||
@@ -62,14 +62,15 @@ class Playlist : public PBD::StatefulDestructible {
|
||||
void unref();
|
||||
uint32_t refcnt() const { return _refcnt; }
|
||||
|
||||
const string& name() const { return _name; }
|
||||
void set_name (const string& str);
|
||||
std::string name() const { return _name; }
|
||||
void set_name (std::string str);
|
||||
|
||||
bool frozen() const { return _frozen; }
|
||||
void set_frozen (bool yn);
|
||||
|
||||
bool hidden() const { return _hidden; }
|
||||
bool empty() const;
|
||||
uint32_t n_regions() const;
|
||||
nframes_t get_maximum_extent () const;
|
||||
layer_t top_layer() const;
|
||||
|
||||
@@ -88,19 +89,15 @@ class Playlist : public PBD::StatefulDestructible {
|
||||
void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
|
||||
void nudge_after (nframes_t start, nframes_t distance, bool forwards);
|
||||
|
||||
boost::shared_ptr<Region> find_region (const PBD::ID&) const;
|
||||
|
||||
Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
|
||||
Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
|
||||
int paste (Playlist&, nframes_t position, float times);
|
||||
|
||||
uint32_t read_data_count() { return _read_data_count; }
|
||||
|
||||
RegionList* regions_at (nframes_t frame);
|
||||
RegionList* regions_touched (nframes_t start, nframes_t end);
|
||||
RegionList* regions_at (nframes_t frame);
|
||||
RegionList* regions_touched (nframes_t start, nframes_t end);
|
||||
boost::shared_ptr<Region> find_region (const PBD::ID&) const;
|
||||
boost::shared_ptr<Region> top_region_at (nframes_t frame);
|
||||
|
||||
boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir);
|
||||
boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir);
|
||||
|
||||
template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg);
|
||||
template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>));
|
||||
|
||||
@@ -163,10 +163,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
|
||||
|
||||
ARDOUR::Playlist* playlist() const { return _playlist; }
|
||||
|
||||
void set_playlist (ARDOUR::Playlist*);
|
||||
|
||||
virtual void lock_sources () {}
|
||||
virtual void unlock_sources () {}
|
||||
virtual void set_playlist (ARDOUR::Playlist*);
|
||||
|
||||
/* serialization */
|
||||
|
||||
|
||||
@@ -542,8 +542,8 @@ class Session : public PBD::StatefulDestructible
|
||||
|
||||
/* region info */
|
||||
|
||||
sigc::signal<void,boost::shared_ptr<AudioRegion> > AudioRegionAdded;
|
||||
sigc::signal<void,boost::shared_ptr<AudioRegion> > AudioRegionRemoved;
|
||||
sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionAdded;
|
||||
sigc::signal<void,boost::weak_ptr<AudioRegion> > AudioRegionRemoved;
|
||||
|
||||
int region_name (string& result, string base = string(""), bool newlevel = false) const;
|
||||
string new_region_name (string);
|
||||
@@ -630,6 +630,7 @@ class Session : public PBD::StatefulDestructible
|
||||
uint32_t n_playlists() const;
|
||||
|
||||
template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
|
||||
void get_playlists (std::vector<Playlist*>&);
|
||||
|
||||
/* named selections */
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define __ardour_source_h__
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
@@ -32,6 +33,7 @@
|
||||
namespace ARDOUR {
|
||||
|
||||
class Session;
|
||||
class Playlist;
|
||||
|
||||
class Source : public PBD::StatefulDestructible
|
||||
{
|
||||
@@ -49,13 +51,23 @@ class Source : public PBD::StatefulDestructible
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&);
|
||||
|
||||
void use () { _in_use++; }
|
||||
void disuse () { if (_in_use) { _in_use--; } }
|
||||
|
||||
void add_playlist (ARDOUR::Playlist*);
|
||||
void remove_playlist (ARDOUR::Playlist*);
|
||||
|
||||
uint32_t used() const;
|
||||
|
||||
protected:
|
||||
Session& _session;
|
||||
string _name;
|
||||
time_t _timestamp;
|
||||
|
||||
std::set<ARDOUR::Playlist*> _playlists;
|
||||
|
||||
private:
|
||||
uint32_t _in_use;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ class Track : public Route
|
||||
|
||||
int set_name (string str, void *src);
|
||||
|
||||
TrackMode mode () const { return _mode; }
|
||||
virtual int set_mode (TrackMode m) { return false; }
|
||||
sigc::signal<void> TrackModeChanged;
|
||||
|
||||
virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
|
||||
nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0;
|
||||
|
||||
@@ -57,9 +61,6 @@ class Track : public Route
|
||||
virtual int use_diskstream (string name) = 0;
|
||||
virtual int use_diskstream (const PBD::ID& id) = 0;
|
||||
|
||||
TrackMode mode() const { return _mode; }
|
||||
void set_mode (TrackMode m);
|
||||
|
||||
nframes_t update_total_latency();
|
||||
void set_latency_delay (nframes_t);
|
||||
|
||||
@@ -88,7 +89,6 @@ class Track : public Route
|
||||
|
||||
void set_meter_point (MeterPoint, void* src);
|
||||
|
||||
sigc::signal<void> ModeChanged;
|
||||
sigc::signal<void> DiskstreamChanged;
|
||||
sigc::signal<void> FreezeChange;
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ AudioDiskstream::setup_destructive_playlist ()
|
||||
void
|
||||
AudioDiskstream::use_destructive_playlist ()
|
||||
{
|
||||
/* this is called from the XML-based constructor. when its done,
|
||||
/* this is called from the XML-based constructor or ::set_destructive. when called,
|
||||
we already have a playlist and a region, but we need to
|
||||
set up our sources for write. we use the sources associated
|
||||
with the (presumed single, full-extent) region.
|
||||
@@ -400,6 +400,10 @@ AudioDiskstream::use_destructive_playlist ()
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
/* be sure to stretch the region out to the maximum length */
|
||||
|
||||
region->set_length (max_frames - region->position(), this);
|
||||
|
||||
uint32_t n;
|
||||
ChannelList::iterator chan;
|
||||
|
||||
@@ -407,6 +411,10 @@ AudioDiskstream::use_destructive_playlist ()
|
||||
(*chan).write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
|
||||
assert((*chan).write_source);
|
||||
(*chan).write_source->set_allow_remove_if_empty (false);
|
||||
|
||||
/* this might be false if we switched modes, so force it */
|
||||
|
||||
(*chan).write_source->set_destructive (true);
|
||||
}
|
||||
|
||||
/* the source list will never be reset for a destructive track */
|
||||
@@ -1584,9 +1592,9 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
|
||||
continue; /* XXX is this OK? */
|
||||
}
|
||||
|
||||
_last_capture_regions.push_back (region);
|
||||
region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region)));
|
||||
|
||||
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
|
||||
_last_capture_regions.push_back (region);
|
||||
|
||||
i_am_the_modifier++;
|
||||
_playlist->add_region (region, (*ci)->start);
|
||||
@@ -2228,3 +2236,60 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::set_destructive (bool yn)
|
||||
{
|
||||
if (yn != destructive()) {
|
||||
|
||||
if (yn) {
|
||||
if (!can_become_destructive ()) {
|
||||
return -1;
|
||||
}
|
||||
_flags |= Destructive;
|
||||
use_destructive_playlist ();
|
||||
} else {
|
||||
_flags &= ~Destructive;
|
||||
reset_write_sources (true, true);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioDiskstream::can_become_destructive () const
|
||||
{
|
||||
if (!_playlist) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* is there only one region ? */
|
||||
|
||||
if (_playlist->n_regions() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Region> first = _playlist->find_next_region (_session.current_start_frame(), Start, 1);
|
||||
assert (first);
|
||||
|
||||
/* do the source(s) for the region cover the session start position ? */
|
||||
|
||||
if (first->position() != _session.current_start_frame()) {
|
||||
if (first->start() > _session.current_start_frame()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* is the source used by only 1 playlist ? */
|
||||
|
||||
boost::shared_ptr<AudioRegion> afirst = boost::dynamic_pointer_cast<AudioRegion> (first);
|
||||
|
||||
assert (afirst);
|
||||
|
||||
if (afirst->source()->used() > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -624,12 +624,10 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
|
||||
|
||||
{
|
||||
RegionLock rlock (this);
|
||||
RegionList::iterator i;
|
||||
RegionList::iterator tmp;
|
||||
|
||||
for (i = regions.begin(); i != regions.end(); ) {
|
||||
for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
|
||||
|
||||
tmp = i;
|
||||
RegionList::iterator tmp = i;
|
||||
++tmp;
|
||||
|
||||
if ((*i) == region) {
|
||||
@@ -639,6 +637,21 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
|
||||
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
for (set<boost::shared_ptr<Region> >::iterator x = all_regions.begin(); x != all_regions.end(); ) {
|
||||
|
||||
set<boost::shared_ptr<Region> >::iterator xtmp = x;
|
||||
++xtmp;
|
||||
|
||||
if ((*x) == region) {
|
||||
all_regions.erase (x);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
x = xtmp;
|
||||
}
|
||||
|
||||
region->set_playlist (0);
|
||||
}
|
||||
|
||||
for (c = _crossfades.begin(); c != _crossfades.end(); ) {
|
||||
|
||||
@@ -72,6 +72,23 @@ AudioTrack::~AudioTrack ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
AudioTrack::set_mode (TrackMode m)
|
||||
{
|
||||
if (m != _mode) {
|
||||
|
||||
if (_diskstream->set_destructive (m == Destructive)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_mode = m;
|
||||
|
||||
TrackModeChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AudioTrack::deprecated_use_diskstream_connections ()
|
||||
{
|
||||
|
||||
@@ -306,6 +306,12 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
|
||||
|
||||
AudioRegion::~AudioRegion ()
|
||||
{
|
||||
if (_playlist) {
|
||||
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
(*i)->remove_playlist (_playlist);
|
||||
}
|
||||
}
|
||||
|
||||
notify_callbacks ();
|
||||
GoingAway (); /* EMIT SIGNAL */
|
||||
}
|
||||
@@ -1145,8 +1151,6 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
|
||||
boost::shared_ptr<Region>
|
||||
AudioRegion::get_parent()
|
||||
{
|
||||
boost::shared_ptr<Region> r;
|
||||
|
||||
if (_playlist) {
|
||||
boost::shared_ptr<AudioRegion> ar;
|
||||
boost::shared_ptr<AudioRegion> grrr2 = boost::dynamic_pointer_cast<AudioRegion> (shared_from_this());
|
||||
@@ -1156,7 +1160,7 @@ AudioRegion::get_parent()
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
return boost::shared_ptr<Region>();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1305,6 +1309,37 @@ AudioRegion::source_offset_changed ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegion::set_playlist (Playlist* pl)
|
||||
{
|
||||
if (pl == _playlist) {
|
||||
return;
|
||||
}
|
||||
|
||||
Playlist* old_playlist = _playlist;
|
||||
|
||||
Region::set_playlist (pl);
|
||||
|
||||
if (pl) {
|
||||
if (old_playlist) {
|
||||
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
(*i)->remove_playlist (old_playlist);
|
||||
(*i)->add_playlist (_playlist);
|
||||
}
|
||||
} else {
|
||||
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
(*i)->add_playlist (_playlist);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (old_playlist) {
|
||||
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
(*i)->remove_playlist (old_playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)
|
||||
|
||||
@@ -392,14 +392,14 @@ Diskstream::set_name (string str)
|
||||
}
|
||||
|
||||
void
|
||||
Diskstream::set_destructive (bool yn)
|
||||
Diskstream::remove_region_from_last_capture (boost::weak_ptr<Region> wregion)
|
||||
{
|
||||
if (yn != destructive()) {
|
||||
reset_write_sources (true, true);
|
||||
if (yn) {
|
||||
_flags |= Destructive;
|
||||
} else {
|
||||
_flags &= ~Destructive;
|
||||
}
|
||||
boost::shared_ptr<Region> region (wregion.lock());
|
||||
|
||||
if (!region) {
|
||||
return;
|
||||
}
|
||||
|
||||
_last_capture_regions.remove (region);
|
||||
}
|
||||
|
||||
|
||||
@@ -85,10 +85,8 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
|
||||
{
|
||||
init (hide);
|
||||
_name = "unnamed"; /* reset by set_state */
|
||||
|
||||
if (set_state (node)) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
/* derived class calls set_state() */
|
||||
}
|
||||
|
||||
Playlist::Playlist (const Playlist& other, string namestr, bool hide)
|
||||
@@ -257,11 +255,19 @@ Playlist::Playlist (Playlist& pl)
|
||||
|
||||
Playlist::~Playlist ()
|
||||
{
|
||||
{
|
||||
RegionLock rl (this);
|
||||
|
||||
for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
|
||||
(*i)->set_playlist (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* GoingAway must be emitted by derived classes */
|
||||
}
|
||||
|
||||
void
|
||||
Playlist::set_name (const string& str)
|
||||
Playlist::set_name (string str)
|
||||
{
|
||||
/* in a typical situation, a playlist is being used
|
||||
by one diskstream and also is referenced by the
|
||||
@@ -1442,13 +1448,21 @@ Playlist::state (bool full_state)
|
||||
bool
|
||||
Playlist::empty() const
|
||||
{
|
||||
RegionLock rlock (const_cast<Playlist *>(this), false);
|
||||
return regions.empty();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Playlist::n_regions() const
|
||||
{
|
||||
RegionLock rlock (const_cast<Playlist *>(this), false);
|
||||
return regions.size();
|
||||
}
|
||||
|
||||
nframes_t
|
||||
Playlist::get_maximum_extent () const
|
||||
{
|
||||
RegionLock rlock (const_cast<Playlist *>(this));
|
||||
RegionLock rlock (const_cast<Playlist *>(this), false);
|
||||
return _get_maximum_extent ();
|
||||
}
|
||||
|
||||
@@ -1475,7 +1489,7 @@ Playlist::bump_name (string name, Session &session)
|
||||
|
||||
do {
|
||||
newname = Playlist::bump_name_once (newname);
|
||||
} while (session.playlist_by_name(newname)!=NULL);
|
||||
} while (session.playlist_by_name (newname)!=NULL);
|
||||
|
||||
return newname;
|
||||
}
|
||||
|
||||
@@ -93,8 +93,7 @@ RegionFactory::create (Session& session, XMLNode& node, bool yn)
|
||||
boost::shared_ptr<Region>
|
||||
RegionFactory::create (SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
|
||||
{
|
||||
AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags);
|
||||
boost::shared_ptr<AudioRegion> arp (ar);
|
||||
boost::shared_ptr<AudioRegion> arp (new AudioRegion (srcs, start, length, name, layer, flags));
|
||||
boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
|
||||
if (announce) {
|
||||
CheckNewRegion (ret);
|
||||
|
||||
@@ -2535,7 +2535,7 @@ Session::remove_region (boost::weak_ptr<Region> weak_region)
|
||||
set_dirty();
|
||||
|
||||
if (removed) {
|
||||
AudioRegionRemoved(ar); /* EMIT SIGNAL */
|
||||
AudioRegionRemoved (ar); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2571,32 +2571,38 @@ Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vec
|
||||
int
|
||||
Session::destroy_region (boost::shared_ptr<Region> region)
|
||||
{
|
||||
boost::shared_ptr<AudioRegion> aregion;
|
||||
|
||||
if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aregion->playlist()) {
|
||||
aregion->playlist()->destroy_region (region);
|
||||
}
|
||||
|
||||
vector<boost::shared_ptr<Source> > srcs;
|
||||
|
||||
for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
|
||||
srcs.push_back (aregion->source (n));
|
||||
|
||||
{
|
||||
boost::shared_ptr<AudioRegion> aregion;
|
||||
|
||||
if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aregion->playlist()) {
|
||||
aregion->playlist()->destroy_region (region);
|
||||
}
|
||||
|
||||
for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
|
||||
srcs.push_back (aregion->source (n));
|
||||
}
|
||||
}
|
||||
|
||||
region->drop_references ();
|
||||
|
||||
for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
|
||||
|
||||
if ((*i).use_count() == 1) {
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
|
||||
|
||||
if (!(*i)->used()) {
|
||||
boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
|
||||
|
||||
if (afs) {
|
||||
(afs)->mark_for_remove ();
|
||||
}
|
||||
|
||||
(*i)->drop_references ();
|
||||
|
||||
cerr << "source was not used by any playlist\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2988,6 +2994,20 @@ Session::add_playlist (Playlist* playlist)
|
||||
PlaylistAdded (playlist); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
Session::get_playlists (vector<Playlist*>& s)
|
||||
{
|
||||
{
|
||||
Glib::Mutex::Lock lm (playlist_lock);
|
||||
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
|
||||
s.push_back (*i);
|
||||
}
|
||||
for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
|
||||
s.push_back (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::track_playlist (Playlist* pl, bool inuse)
|
||||
{
|
||||
|
||||
@@ -520,7 +520,6 @@ Session::create (bool& new_session, string* mix_template, nframes_t initial_leng
|
||||
_state_of_the_state = Clean;
|
||||
|
||||
if (save_state (_current_snapshot_name)) {
|
||||
save_history (_current_snapshot_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2456,6 +2455,8 @@ Session::cleanup_sources (Session::cleanup_report& rep)
|
||||
capture files.
|
||||
*/
|
||||
|
||||
cerr << "checking out source " << i->second->name() << " use_count = " << i->second.use_count() << endl;
|
||||
|
||||
if (i->second.use_count() == 1 && i->second->length() > 0) {
|
||||
dead_sources.push_back (i->second);
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ SndFileSource::init (string idstr)
|
||||
_capture_end = false;
|
||||
file_pos = 0;
|
||||
|
||||
if (destructive()) {
|
||||
if (destructive()) {
|
||||
xfade_buf = new Sample[xfade_frames];
|
||||
timeline_position = header_position_offset;
|
||||
}
|
||||
@@ -680,11 +680,15 @@ SndFileSource::set_destructive (bool yn)
|
||||
{
|
||||
if (yn) {
|
||||
_flags = Flag (_flags | Destructive);
|
||||
if (!xfade_buf) {
|
||||
xfade_buf = new Sample[xfade_frames];
|
||||
}
|
||||
clear_capture_marks ();
|
||||
timeline_position = header_position_offset;
|
||||
} else {
|
||||
_flags = Flag (_flags & ~Destructive);
|
||||
timeline_position = 0;
|
||||
/* leave xfade buf alone in case we need it again later */
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <pbd/pthread_utils.h>
|
||||
|
||||
#include <ardour/source.h>
|
||||
#include <ardour/playlist.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
@@ -47,12 +48,14 @@ Source::Source (Session& s, string name)
|
||||
{
|
||||
_name = name;
|
||||
_timestamp = 0;
|
||||
_in_use = 0;
|
||||
}
|
||||
|
||||
Source::Source (Session& s, const XMLNode& node)
|
||||
: _session (s)
|
||||
{
|
||||
_timestamp = 0;
|
||||
_in_use = 0;
|
||||
|
||||
if (set_state (node)) {
|
||||
throw failed_constructor();
|
||||
@@ -106,3 +109,24 @@ Source::set_state (const XMLNode& node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Source::add_playlist (Playlist* pl)
|
||||
{
|
||||
_playlists.insert (pl);
|
||||
}
|
||||
|
||||
void
|
||||
Source::remove_playlist (Playlist* pl)
|
||||
{
|
||||
std::set<Playlist*>::iterator x;
|
||||
|
||||
if ((x = _playlists.find (pl)) != _playlists.end()) {
|
||||
_playlists.erase (x);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Source::used () const
|
||||
{
|
||||
return _playlists.size();
|
||||
}
|
||||
|
||||
@@ -183,18 +183,6 @@ Track::set_record_enable (bool yn, void *src)
|
||||
_rec_enable_control.Changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Track::set_mode (TrackMode m)
|
||||
{
|
||||
if (_diskstream) {
|
||||
if (_mode != m) {
|
||||
_mode = m;
|
||||
_diskstream->set_destructive (m == Destructive);
|
||||
ModeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Track::set_name (string str, void *src)
|
||||
{
|
||||
|
||||
@@ -423,6 +423,7 @@ BarController::switch_to_spinner ()
|
||||
remove ();
|
||||
add (spinner);
|
||||
spinner.show ();
|
||||
spinner.select_region (0, spinner.get_text_length());
|
||||
spinner.grab_focus ();
|
||||
|
||||
switching = false;
|
||||
|
||||
Reference in New Issue
Block a user