fix from 2.X for automation line clear command using the wrong object in the memento...
[ardour.git] / gtk2_ardour / audio_region_view.cc
index ca3c8b3ba1c6803c0abeeb60e014939ab9f36ec4..d490ede63b4e7380064078ba33b322fb4e531099 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2001-2006 Paul Davis 
+    Copyright (C) 2001-2006 Paul Davis
 
     This program is free software; you can r>edistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -27,8 +27,8 @@
 #include "ardour/playlist.h"
 #include "ardour/audioregion.h"
 #include "ardour/audiosource.h"
-#include "ardour/audio_diskstream.h"
 #include "ardour/profile.h"
+#include "ardour/session.h"
 
 #include "pbd/memento_command.h"
 #include "pbd/stacktrace.h"
@@ -57,7 +57,6 @@
 #define MUTED_ALPHA 10
 
 using namespace std;
-using namespace sigc;
 using namespace ARDOUR;
 using namespace PBD;
 using namespace Editing;
@@ -82,7 +81,7 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
 }
 
 
-AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu, 
+AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
                                  Gdk::Color const & basic_color, bool recording, TimeAxisViewItem::Visibility visibility)
        : RegionView (parent, tv, r, spu, basic_color, recording, visibility)
        , sync_mark(0)
@@ -111,14 +110,13 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other)
        , _amplitude_above_axis(1.0)
        , _flags(0)
        , fade_color(0)
-
 {
        Gdk::Color c;
        int r,g,b,a;
 
        UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
        c.set_rgb_p (r/255.0, g/255.0, b/255.0);
-       
+
        init (c, false);
 }
 
@@ -133,7 +131,6 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
        , _amplitude_above_axis(1.0)
        , _flags(0)
        , fade_color(0)
-
 {
        Gdk::Color c;
        int r,g,b,a;
@@ -149,9 +146,9 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
 {
        // FIXME: Some redundancy here with RegionView::init.  Need to figure out
        // where order is important and where it isn't...
-       
+
        RegionView::init (basic_color, wfd);
-       
+
        XMLNode *node;
 
        _amplitude_above_axis = 1.0;
@@ -165,18 +162,19 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
                store_flags ();
        }
 
-       if (trackview.editor().new_regionviews_display_gain()) {
+       /* make envelope visible if it has anything interesting in it */
+       if (audio_region()->envelope()->size() > 2) {
                _flags |= EnvelopeVisible;
        }
 
        compute_colors (basic_color);
-       
+
        create_waves ();
 
        fade_in_shape = new ArdourCanvas::Polygon (*group);
        fade_in_shape->property_fill_color_rgba() = fade_color;
        fade_in_shape->set_data ("regionview", this);
-       
+
        fade_out_shape = new ArdourCanvas::Polygon (*group);
        fade_out_shape->property_fill_color_rgba() = fade_color;
        fade_out_shape->set_data ("regionview", this);
@@ -184,31 +182,30 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
        {
                uint32_t r,g,b,a;
                UINT_TO_RGBA(fill_color,&r,&g,&b,&a);
-       
+
                fade_in_handle = new ArdourCanvas::SimpleRect (*group);
                fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
                fade_in_handle->property_outline_pixels() = 0;
-               
+
                fade_in_handle->set_data ("regionview", this);
-               
+
                fade_out_handle = new ArdourCanvas::SimpleRect (*group);
                fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
                fade_out_handle->property_outline_pixels() = 0;
-               
+
                fade_out_handle->set_data ("regionview", this);
        }
 
        setup_fade_handle_positions ();
 
-       if (!trackview.session().config.get_show_region_fades()) {
-               set_fade_visibility (false);
-       }
+       if (!trackview.session()->config.get_show_region_fades()) {
+               set_fade_visibility (false);
+       }
 
        const string line_name = _region->name() + ":gain";
 
        if (!Profile->get_sae()) {
-               gain_line = new AudioRegionGainLine (line_name, trackview.session(), *this, *group,
-                               audio_region()->envelope());
+               gain_line = new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope());
        }
 
        if (!(_flags & EnvelopeVisible)) {
@@ -223,7 +220,8 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
 
        region_muted ();
        region_sync_changed ();
-       region_resized (BoundsChanged);
+
+       region_resized (ARDOUR::bounds_change);
        set_waveview_data_src();
        region_locked ();
        envelope_active_changed ();
@@ -232,10 +230,10 @@ AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
 
        reset_width_dependent_items (_pixel_width);
 
-       fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this));
-       fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this));
-       fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this));
-       fade_out_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this));
+       fade_in_shape->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this));
+       fade_in_handle->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this));
+       fade_out_shape->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this));
+       fade_out_handle->signal_event().connect (sigc::bind (sigc::mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this));
 
        set_colors ();
 
@@ -252,6 +250,10 @@ AudioRegionView::~AudioRegionView ()
                gnome_canvas_waveview_cache_destroy (*cache);
        }
 
+       for (vector<ScopedConnection*>::iterator i = _data_ready_connections.begin(); i != _data_ready_connections.end(); ++i) {
+               delete *i;
+       }
+
        /* all waveviews etc will be destroyed when the group is destroyed */
 
        delete gain_line;
@@ -265,29 +267,29 @@ AudioRegionView::audio_region() const
 }
 
 void
-AudioRegionView::region_changed (Change what_changed)
+AudioRegionView::region_changed (const PropertyChange& what_changed)
 {
-       ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed));
-       //cerr << "AudioRegionView::region_changed() called" << endl;
+       ENSURE_GUI_THREAD (*this, &AudioRegionView::region_changed, what_changed);
+        // cerr << "AudioRegionView::region_changed() called" << endl;
 
-       RegionView::region_changed(what_changed);
+       RegionView::region_changed (what_changed);
 
-       if (what_changed & AudioRegion::ScaleAmplitudeChanged) {
+       if (what_changed.contains (ARDOUR::Properties::scale_amplitude)) {
                region_scale_amplitude_changed ();
        }
-       if (what_changed & AudioRegion::FadeInChanged) {
-               fade_in_changed ();
+       if (what_changed.contains (ARDOUR::Properties::fade_in)) {
+                fade_in_changed ();
        }
-       if (what_changed & AudioRegion::FadeOutChanged) {
+       if (what_changed.contains (ARDOUR::Properties::fade_out)) {
                fade_out_changed ();
        }
-       if (what_changed & AudioRegion::FadeInActiveChanged) {
+       if (what_changed.contains (ARDOUR::Properties::fade_in_active)) {
                fade_in_active_changed ();
        }
-       if (what_changed & AudioRegion::FadeOutActiveChanged) {
+       if (what_changed.contains (ARDOUR::Properties::fade_out_active)) {
                fade_out_active_changed ();
        }
-       if (what_changed & AudioRegion::EnvelopeActiveChanged) {
+       if (what_changed.contains (ARDOUR::Properties::envelope_active)) {
                envelope_active_changed ();
        }
 }
@@ -315,7 +317,7 @@ AudioRegionView::fade_in_active_changed ()
                fade_in_shape->property_fill_color_rgba() = col;
                fade_in_shape->property_width_pixels() = 0;
                fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
-       } else { 
+       } else {
                col = RGBA_TO_UINT(r,g,b,0);
                fade_in_shape->property_fill_color_rgba() = col;
                fade_in_shape->property_width_pixels() = 1;
@@ -335,7 +337,7 @@ AudioRegionView::fade_out_active_changed ()
                fade_out_shape->property_fill_color_rgba() = col;
                fade_out_shape->property_width_pixels() = 0;
                fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
-       } else { 
+       } else {
                col = RGBA_TO_UINT(r,g,b,0);
                fade_out_shape->property_fill_color_rgba() = col;
                fade_out_shape->property_width_pixels() = 1;
@@ -347,7 +349,7 @@ AudioRegionView::fade_out_active_changed ()
 void
 AudioRegionView::region_scale_amplitude_changed ()
 {
-       ENSURE_GUI_THREAD (mem_fun(*this, &AudioRegionView::region_scale_amplitude_changed));
+       ENSURE_GUI_THREAD (*this, &AudioRegionView::region_scale_amplitude_changed)
 
        for (uint32_t n = 0; n < waves.size(); ++n) {
                // force a reload of the cache
@@ -359,8 +361,8 @@ void
 AudioRegionView::region_renamed ()
 {
        Glib::ustring str = RegionView::make_name ();
-       
-       if (audio_region()->speed_mismatch (trackview.session().frame_rate())) {
+
+       if (audio_region()->speed_mismatch (trackview.session()->frame_rate())) {
                str = string ("*") + str;
        }
 
@@ -373,26 +375,30 @@ AudioRegionView::region_renamed ()
 }
 
 void
-AudioRegionView::region_resized (Change what_changed)
+AudioRegionView::region_resized (const PropertyChange& what_changed)
 {
        AudioGhostRegion* agr;
 
        RegionView::region_resized(what_changed);
+       PropertyChange interesting_stuff;
 
-       if (what_changed & Change (StartChanged|LengthChanged)) {
+       interesting_stuff.add (ARDOUR::Properties::start);
+       interesting_stuff.add (ARDOUR::Properties::length);
 
-               for (uint32_t n = 0; n < waves.size(); ++n) {
-                       waves[n]->property_region_start() = _region->start();
+       if (what_changed.contains (interesting_stuff)) {
+
+               for (uint32_t n = 0; n < waves.size(); ++n) {
+                       waves[n]->property_region_start() = _region->start();
                }
-               
-               for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+
+               for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
                        if((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
 
                                for (vector<WaveView*>::iterator w = agr->waves.begin(); w != agr->waves.end(); ++w) {
                                        (*w)->property_region_start() = _region->start();
                                }
                        }
-               }
+               }
        }
 }
 
@@ -415,7 +421,7 @@ AudioRegionView::reset_width_dependent_items (double pixel_width)
                                fade_in_handle->hide();
                                fade_out_handle->hide();
                        } else {
-                               if (trackview.session().config.get_show_region_fades()) {
+                               if (trackview.session()->config.get_show_region_fades()) {
                                        fade_in_handle->show();
                                        fade_out_handle->show();
                                }
@@ -452,7 +458,7 @@ AudioRegionView::setup_fade_handle_positions()
                fade_in_handle->property_y1() = handle_pos;
                fade_in_handle->property_y2() = handle_pos + handle_height;
        }
-       
+
        if (fade_out_handle) {
                fade_out_handle->property_y1() = handle_pos;
                fade_out_handle->property_y2() = handle_pos + handle_height;
@@ -468,25 +474,24 @@ AudioRegionView::set_height (gdouble height)
 
        // FIXME: ick
        height -= 2;
-       
-       _height = height;
 
-       for (uint32_t n=0; n < wcnt; ++n) {
+       for (uint32_t n = 0; n < wcnt; ++n) {
                gdouble ht;
 
                if ((height) < NAME_HIGHLIGHT_THRESH) {
-                       ht = ((height-2*wcnt) / (double) wcnt);
+                       ht = ((height - 2 * wcnt) / (double) wcnt);
                } else {
-                       ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
+                       ht = (((height - 2 * wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
                }
-               
-               gdouble yoff = n * (ht+1);
-               
+
+               gdouble yoff = n * (ht + 1);
+
                waves[n]->property_height() = ht;
                waves[n]->property_y() = yoff + 2;
        }
 
        if (gain_line) {
+
                if ((height/wcnt) < NAME_HIGHLIGHT_THRESH) {
                        gain_line->hide ();
                } else {
@@ -494,7 +499,8 @@ AudioRegionView::set_height (gdouble height)
                                gain_line->show ();
                        }
                }
-               gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE));
+
+               gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
        }
 
        manage_zero_line ();
@@ -503,7 +509,6 @@ AudioRegionView::set_height (gdouble height)
        if (name_pixbuf) {
                name_pixbuf->raise_to_top();
        }
-
 }
 
 void
@@ -535,7 +540,7 @@ AudioRegionView::reset_fade_in_shape ()
 {
        reset_fade_in_shape_width ((nframes_t) audio_region()->fade_in()->back()->when);
 }
-       
+
 void
 AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 {
@@ -550,8 +555,8 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
        Points* points;
        double pwidth = width / samples_per_unit;
        uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth);
-       double h; 
-       
+       double h;
+
        if (_height < 5) {
                fade_in_shape->hide();
                fade_in_handle->hide();
@@ -560,7 +565,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 
        double handle_center;
        handle_center = pwidth;
-       
+
        if (handle_center > 7.0) {
                handle_center -= 3.0;
        } else {
@@ -569,13 +574,13 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 
        fade_in_handle->property_x1() =  handle_center - 3.0;
        fade_in_handle->property_x2() =  handle_center + 3.0;
-       
+
        if (pwidth < 5) {
                fade_in_shape->hide();
                return;
        }
 
-       if (trackview.session().config.get_show_region_fades()) {
+       if (trackview.session()->config.get_show_region_fades()) {
                fade_in_shape->show();
        }
 
@@ -599,7 +604,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
                (*points)[pi].set_x(1 + (pc * xdelta));
                (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
        }
-       
+
        /* fold back */
 
        (*points)[pi].set_x(pwidth);
@@ -611,9 +616,12 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
        /* connect the dots ... */
 
        (*points)[pi] = (*points)[0];
-       
+
        fade_in_shape->property_points() = *points;
        delete points;
+
+       /* ensure trim handle stays on top */
+       frame_handle_start->raise_to_top();
 }
 
 void
@@ -624,7 +632,7 @@ AudioRegionView::reset_fade_out_shape ()
 
 void
 AudioRegionView::reset_fade_out_shape_width (nframes_t width)
-{      
+{
        if (fade_out_handle == 0) {
                return;
        }
@@ -646,24 +654,24 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
 
        double handle_center;
        handle_center = (_region->length() - width) / samples_per_unit;
-       
+
        if (handle_center > 7.0) {
                handle_center -= 3.0;
        } else {
                handle_center = 3.0;
        }
-       
+
        fade_out_handle->property_x1() =  handle_center - 3.0;
        fade_out_handle->property_x2() =  handle_center + 3.0;
 
        /* don't show shape if its too small */
-       
+
        if (pwidth < 5) {
                fade_out_shape->hide();
                return;
-       } 
-       
-       if (trackview.session().config.get_show_region_fades()) {
+       }
+
+       if (trackview.session()->config.get_show_region_fades()) {
                fade_out_shape->show();
        }
 
@@ -687,7 +695,7 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
                (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta));
                (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
        }
-       
+
        /* fold back */
 
        (*points)[pi].set_x(_pixel_width);
@@ -702,6 +710,9 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
 
        fade_out_shape->property_points() = *points;
        delete points;
+
+       /* ensure trim handle stays on top */
+       frame_handle_end->raise_to_top();
 }
 
 void
@@ -734,7 +745,7 @@ void
 AudioRegionView::compute_colors (Gdk::Color const & basic_color)
 {
        RegionView::compute_colors (basic_color);
-       
+
        uint32_t r, g, b, a;
 
        /* gain color computed in envelope_active_changed() */
@@ -747,7 +758,7 @@ void
 AudioRegionView::set_colors ()
 {
        RegionView::set_colors();
-       
+
        if (gain_line) {
                gain_line->set_line_color (audio_region()->envelope_active() ? ARDOUR_UI::config()->canvasvar_GainLine.get() : ARDOUR_UI::config()->canvasvar_GainLineInactive.get());
        }
@@ -772,7 +783,7 @@ AudioRegionView::show_region_editor ()
                // GTK2FIX : how to ensure float without realizing
                // editor->realize ();
                // trackview.editor.ensure_float (*editor);
-       } 
+       }
 
        editor->present ();
        editor->show_all();
@@ -838,32 +849,42 @@ AudioRegionView::create_waves ()
        // cerr << "AudioRegionView::create_waves() called on " << this << endl;//DEBUG
        RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
 
-       if (!atv.get_diskstream()) {
+       if (!atv.track()) {
                return;
        }
 
-       ChanCount nchans = atv.get_diskstream()->n_channels();
+       ChanCount nchans = atv.track()->n_channels();
 
        // cerr << "creating waves for " << _region->name() << " with wfd = " << wait_for_data
        //              << " and channels = " << nchans.n_audio() << endl;
-       
+
        /* in tmp_waves, set up null pointers for each channel so the vector is allocated */
        for (uint32_t n = 0; n < nchans.n_audio(); ++n) {
                tmp_waves.push_back (0);
        }
 
+       for (vector<ScopedConnection*>::iterator i = _data_ready_connections.begin(); i != _data_ready_connections.end(); ++i) {
+               delete *i;
+       }
+
+       _data_ready_connections.clear ();
+
+       for (uint32_t i = 0; i < nchans.n_audio(); ++i) {
+               _data_ready_connections.push_back (0);
+       }
+
        for (uint32_t n = 0; n < nchans.n_audio(); ++n) {
-               
+
                if (n >= audio_region()->n_channels()) {
                        break;
                }
-               
+
                wave_caches.push_back (WaveView::create_cache ());
 
                // cerr << "\tchannel " << n << endl;
 
                if (wait_for_data) {
-                       if (audio_region()->audio_source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
+                       if (audio_region()->audio_source(n)->peaks_ready (boost::bind (&AudioRegionView::peaks_ready_handler, this, n), &_data_ready_connections[n], gui_context())) {
                                // cerr << "\tData is ready\n";
                                create_one_wave (n, true);
                        } else {
@@ -871,7 +892,7 @@ AudioRegionView::create_waves ()
                                // we'll get a PeaksReady signal from the source in the future
                                // and will call create_one_wave(n) then.
                        }
-                       
+
                } else {
                        // cerr << "\tdon't delay, display today!\n";
                        create_one_wave (n, true);
@@ -881,11 +902,11 @@ AudioRegionView::create_waves ()
 }
 
 void
-AudioRegionView::create_one_wave (uint32_t which, bool direct)
+AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
 {
        //cerr << "AudioRegionView::create_one_wave() called which: " << which << " this: " << this << endl;//DEBUG
        RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
-       uint32_t nchans = atv.get_diskstream()->n_channels().n_audio();
+       uint32_t nchans = atv.track()->n_channels().n_audio();
        uint32_t n;
        uint32_t nwaves = std::min (nchans, audio_region()->n_channels());
        gdouble ht;
@@ -942,9 +963,9 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
        } else {
                /* n-channel track, >n-channel source */
        }
-       
+
        /* see if we're all ready */
-       
+
        for (n = 0; n < nchans; ++n) {
                if (tmp_waves[n] == 0) {
                        break;
@@ -959,7 +980,8 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
                tmp_waves.clear ();
 
                /* all waves created, don't hook into peaks ready anymore */
-               data_ready_connection.disconnect ();            
+               delete _data_ready_connections[which];
+               _data_ready_connections[which] = 0;
 
 #if 0
                if (!zero_line) {
@@ -976,7 +998,7 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
 void
 AudioRegionView::peaks_ready_handler (uint32_t which)
 {
-       Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &AudioRegionView::create_one_wave), which, false));
+       Gtkmm2ext::UI::instance()->call_slot (invalidator (*this), boost::bind (&AudioRegionView::create_one_wave, this, which, false));
        // cerr << "AudioRegionView::peaks_ready_handler() called on " << which << " this: " << this << endl;
 }
 
@@ -992,7 +1014,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
        /* don't create points that can't be seen */
 
        set_envelope_visible (true);
-       
+
        x = ev->button.x;
        y = ev->button.y;
 
@@ -1012,25 +1034,29 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
 
        gain_line->view_to_model_coord (x, y);
 
-       trackview.session().begin_reversible_command (_("add gain control point"));
+        /* XXX STATEFUL: can't convert to stateful diff until we 
+           can represent automation data with it.
+        */
+
+       trackview.session()->begin_reversible_command (_("add gain control point"));
        XMLNode &before = audio_region()->envelope()->get_state();
 
        if (!audio_region()->envelope_active()) {
                XMLNode &region_before = audio_region()->get_state();
                audio_region()->set_envelope_active(true);
                XMLNode &region_after = audio_region()->get_state();
-               trackview.session().add_command (new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after));
+               trackview.session()->add_command (new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after));
        }
 
        audio_region()->envelope()->add (fx, y);
-       
+
        XMLNode &after = audio_region()->envelope()->get_state();
-       trackview.session().add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
-       trackview.session().commit_reversible_command ();
+       trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
+       trackview.session()->commit_reversible_command ();
 }
 
 void
-AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
+AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent */*ev*/)
 {
        ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
        audio_region()->envelope()->erase (cp->model());
@@ -1055,36 +1081,36 @@ AudioRegionView::set_flags (XMLNode* node)
        XMLProperty *prop;
 
        if ((prop = node->property ("waveform-visible")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= WaveformVisible;
                }
        }
 
        if ((prop = node->property ("envelope-visible")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= EnvelopeVisible;
                }
        }
 
        if ((prop = node->property ("waveform-rectified")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= WaveformRectified;
                }
        }
 
        if ((prop = node->property ("waveform-logscaled")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= WaveformLogScaled;
                }
        }
 }
-       
+
 void
 AudioRegionView::set_waveform_shape (WaveformShape shape)
 {
        bool yn;
 
-       /* this slightly odd approach is to leave the door open to 
+       /* this slightly odd approach is to leave the door open to
           other "shapes" such as spectral displays, etc.
        */
 
@@ -1149,15 +1175,15 @@ AudioRegionView::add_ghost (TimeAxisView& tv)
        double unit_position = _region->position () / samples_per_unit;
        AudioGhostRegion* ghost = new AudioGhostRegion (tv, trackview, unit_position);
        uint32_t nchans;
-       
-       nchans = rtv->get_diskstream()->n_channels().n_audio();
+
+       nchans = rtv->track()->n_channels().n_audio();
 
        for (uint32_t n = 0; n < nchans; ++n) {
-               
+
                if (n >= audio_region()->n_channels()) {
                        break;
                }
-               
+
                WaveView *wave = new WaveView(*ghost->group);
 
                wave->property_data_src() = _region.get();
@@ -1181,8 +1207,6 @@ AudioRegionView::add_ghost (TimeAxisView& tv)
        ghost->set_colors();
        ghosts.push_back (ghost);
 
-       ghost->GoingAway.connect (mem_fun(*this, &AudioRegionView::remove_ghost));
-
        return ghost;
 }
 
@@ -1196,7 +1220,7 @@ AudioRegionView::entered ()
        uint32_t r,g,b,a;
        UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
        a=255;
-       
+
        if (fade_in_handle) {
                fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
                fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
@@ -1209,11 +1233,11 @@ AudioRegionView::exited ()
        if (gain_line) {
                gain_line->hide_all_but_selected_control_points ();
        }
-       
+
        uint32_t r,g,b,a;
        UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
        a=0;
-       
+
        if (fade_in_handle) {
                fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
                fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
@@ -1238,11 +1262,11 @@ AudioRegionView::set_waveview_data_src()
                // TODO: something else to let it know the channel
                waves[n]->property_data_src() = _region.get();
        }
-       
+
        for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
-               
+
                (*i)->set_duration (unit_length);
-               
+
                if((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
                        for (vector<WaveView*>::iterator w = agr->waves.begin(); w != agr->waves.end(); ++w) {
                                (*w)->property_data_src() = _region.get();
@@ -1281,7 +1305,7 @@ AudioRegionView::set_frame_color ()
        }
 
        uint32_t r,g,b,a;
-       
+
        if (_selected && should_show_selection) {
                UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
                frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
@@ -1332,10 +1356,10 @@ AudioRegionView::set_fade_visibility (bool yn)
                }
                if (fade_out_shape) {
                        fade_out_shape->show ();
-               } 
+               }
                if (fade_in_handle) {
                        fade_in_handle->show ();
-               } 
+               }
                if (fade_out_handle) {
                        fade_out_handle->show ();
                }
@@ -1345,12 +1369,21 @@ AudioRegionView::set_fade_visibility (bool yn)
                }
                if (fade_out_shape) {
                        fade_out_shape->hide ();
-               } 
+               }
                if (fade_in_handle) {
                        fade_in_handle->hide ();
-               } 
+               }
                if (fade_out_handle) {
                        fade_out_handle->hide ();
                }
        }
 }
+
+void
+AudioRegionView::update_coverage_frames (LayerDisplay d)
+{
+       RegionView::update_coverage_frames (d);
+
+       fade_in_handle->raise_to_top ();
+       fade_out_handle->raise_to_top ();
+}