fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / export_format_manager.cc
index a1d1b726296248d77551a0a07c965e44fdf82a89..4025ad37c7f1e8774366f3e98b382edb738d155d 100644 (file)
 
 */
 
-#include <ardour/export_format_manager.h>
+#include "ardour/export_format_manager.h"
 
-#include <ardour/types.h>
-#include <ardour/export_format_specification.h>
-#include <ardour/export_format_compatibility.h>
+#include "ardour/export_format_specification.h"
+#include "ardour/export_format_compatibility.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
+
+using std::string;
 
 namespace ARDOUR
 {
 
-ExportFormatManager::ExportFormatManager (SpecPtr specification) :
+ExportFormatManager::ExportFormatManager (ExportFormatSpecPtr specification) :
   pending_selection_change (false),
   universal_set (new ExportFormatBase ())
 {
@@ -39,6 +40,8 @@ ExportFormatManager::ExportFormatManager (SpecPtr specification) :
        init_qualities ();
        init_formats ();
        init_sample_rates ();
+
+       prev_description = current_selection->description();
 }
 
 ExportFormatManager::~ExportFormatManager ()
@@ -48,9 +51,9 @@ ExportFormatManager::~ExportFormatManager ()
 
 void
 ExportFormatManager::init_compatibilities ()
-{      
-       CompatPtr c_ptr;
-       
+{
+       ExportFormatCompatibilityPtr c_ptr;
+
        c_ptr.reset (new ExportFormatCompatibility (_("CD")));
        c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
        c_ptr->add_format_id (ExportFormatBase::F_WAV);
@@ -59,7 +62,7 @@ ExportFormatManager::init_compatibilities ()
        c_ptr->add_sample_format (ExportFormatBase::SF_16);
        c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
        add_compatibility (c_ptr);
-       
+
        c_ptr.reset (new ExportFormatCompatibility (_("DVD-A")));
        c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
        c_ptr->add_sample_rate (ExportFormatBase::SR_48);
@@ -73,7 +76,7 @@ ExportFormatManager::init_compatibilities ()
        c_ptr->add_sample_format (ExportFormatBase::SF_24);
        c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
        add_compatibility (c_ptr);
-       
+
        c_ptr.reset (new ExportFormatCompatibility (_("iPod")));
        c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
        c_ptr->add_sample_rate (ExportFormatBase::SR_48);
@@ -84,7 +87,7 @@ ExportFormatManager::init_compatibilities ()
        c_ptr->add_sample_format (ExportFormatBase::SF_24);
        c_ptr->add_endianness (ExportFormatBase::E_FileDefault);
        add_compatibility (c_ptr);
-       
+
        c_ptr.reset (new ExportFormatCompatibility (_("Something else")));
        c_ptr->add_sample_rate (ExportFormatBase::SR_44_1);
        c_ptr->add_sample_rate (ExportFormatBase::SR_48);
@@ -112,10 +115,10 @@ ExportFormatManager::init_qualities ()
 
 void
 ExportFormatManager::init_formats ()
-{      
-       FormatPtr f_ptr;
+{
+       ExportFormatPtr f_ptr;
        ExportFormatLinear * fl_ptr;
-       
+
        f_ptr.reset (fl_ptr = new ExportFormatLinear ("AIFF", ExportFormatBase::F_AIFF));
        fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
        fl_ptr->add_sample_format (ExportFormatBase::SF_8);
@@ -124,10 +127,11 @@ ExportFormatManager::init_formats ()
        fl_ptr->add_sample_format (ExportFormatBase::SF_32);
        fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
        fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
+       fl_ptr->add_endianness (ExportFormatBase::E_Big);
        fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
        fl_ptr->set_extension ("aiff");
        add_format (f_ptr);
-       
+
        f_ptr.reset (fl_ptr = new ExportFormatLinear ("AU", ExportFormatBase::F_AU));
        fl_ptr->add_sample_format (ExportFormatBase::SF_8);
        fl_ptr->add_sample_format (ExportFormatBase::SF_16);
@@ -138,10 +142,10 @@ ExportFormatManager::init_formats ()
        fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
        fl_ptr->set_extension ("au");
        add_format (f_ptr);
-       
+
        f_ptr.reset (new ExportFormatBWF ());
        add_format (f_ptr);
-       
+
        f_ptr.reset (fl_ptr = new ExportFormatLinear ("IRCAM", ExportFormatBase::F_IRCAM));
        fl_ptr->add_sample_format (ExportFormatBase::SF_16);
        fl_ptr->add_sample_format (ExportFormatBase::SF_24);
@@ -150,7 +154,7 @@ ExportFormatManager::init_formats ()
        fl_ptr->set_default_sample_format (ExportFormatBase::SF_24);
        fl_ptr->set_extension ("sf");
        add_format (f_ptr);
-       
+
        f_ptr.reset (fl_ptr = new ExportFormatLinear ("WAV", ExportFormatBase::F_WAV));
        fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
        fl_ptr->add_sample_format (ExportFormatBase::SF_16);
@@ -158,10 +162,11 @@ ExportFormatManager::init_formats ()
        fl_ptr->add_sample_format (ExportFormatBase::SF_32);
        fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
        fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
+       fl_ptr->add_endianness (ExportFormatBase::E_Little);
        fl_ptr->set_default_sample_format (ExportFormatBase::SF_16);
        fl_ptr->set_extension ("wav");
        add_format (f_ptr);
-       
+
        f_ptr.reset (fl_ptr = new ExportFormatLinear ("W64", ExportFormatBase::F_W64));
        fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
        fl_ptr->add_sample_format (ExportFormatBase::SF_16);
@@ -172,7 +177,18 @@ ExportFormatManager::init_formats ()
        fl_ptr->set_default_sample_format (ExportFormatBase::SF_Double);
        fl_ptr->set_extension ("w64");
        add_format (f_ptr);
-       
+
+       f_ptr.reset (fl_ptr = new ExportFormatLinear ("CAF", ExportFormatBase::F_CAF));
+       fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
+       fl_ptr->add_sample_format (ExportFormatBase::SF_16);
+       fl_ptr->add_sample_format (ExportFormatBase::SF_24);
+       fl_ptr->add_sample_format (ExportFormatBase::SF_32);
+       fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
+       fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
+       fl_ptr->set_default_sample_format (ExportFormatBase::SF_Float);
+       fl_ptr->set_extension ("caf");
+       add_format (f_ptr);
+
        f_ptr.reset (fl_ptr = new ExportFormatLinear ("RAW", ExportFormatBase::F_RAW));
        fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
        fl_ptr->add_sample_format (ExportFormatBase::SF_8);
@@ -184,131 +200,193 @@ ExportFormatManager::init_formats ()
        fl_ptr->set_default_sample_format (ExportFormatBase::SF_Float);
        fl_ptr->set_extension ("raw");
        add_format (f_ptr);
-       
-       if (ExportFormatOggVorbis::check_system_compatibility()) {
+
+       try {
                f_ptr.reset (new ExportFormatOggVorbis ());
                add_format (f_ptr);
-       }
-       
-       if (ExportFormatFLAC::check_system_compatibility()) {
+       } catch (ExportFormatIncompatible & e) {}
+
+       try {
                f_ptr.reset (new ExportFormatFLAC ());
                add_format (f_ptr);
-       }
+       } catch (ExportFormatIncompatible & e) {}
 }
 
 void
 ExportFormatManager::init_sample_rates ()
 {
-       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_22_05, "22,05 kHz")));
-       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_44_1, "44,1 kHz")));
-       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_48, "48 kHz")));      
-       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_88_2, "88,2 kHz")));  
-       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_96, "96 kHz")));      
-       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_192, "192 kHz")));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_Session, _("Session rate"))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_8,     string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(0), 8))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_22_05, string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(2), 22.05))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_44_1,  string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(1), 44.1))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_48,    string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(0), 48))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_88_2,  string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(1), 88.2))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_96,    string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(0), 96))));
+       add_sample_rate (SampleRatePtr (new SampleRateState (ExportFormatBase::SR_192,   string_compose ("%1%2%3 kHz", std::fixed, std::setprecision(0), 192))));
 }
 
 void
-ExportFormatManager::add_compatibility (CompatPtr ptr)
+ExportFormatManager::add_compatibility (ExportFormatCompatibilityPtr ptr)
 {
        compatibilities.push_back (ptr);
-       ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_compatibility_selection), WeakCompatPtr (ptr)));
+       ptr->SelectChanged.connect_same_thread (*this,
+                                               boost::bind (&ExportFormatManager::change_compatibility_selection,
+                                                            this, _1, WeakExportFormatCompatibilityPtr (ptr)));
 }
 
 void
 ExportFormatManager::add_quality (QualityPtr ptr)
 {
-       ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_quality_selection), WeakQualityPtr (ptr)));
+       ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_quality_selection, this, _1, WeakQualityPtr (ptr)));
        qualities.push_back (ptr);
 }
 
 void
-ExportFormatManager::add_format (FormatPtr ptr)
+ExportFormatManager::add_format (ExportFormatPtr ptr)
 {
        formats.push_back (ptr);
-       ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_format_selection), WeakFormatPtr (ptr)));
+       ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_format_selection, this, _1, WeakExportFormatPtr (ptr)));
        universal_set = universal_set->get_union (*ptr);
-       
+
        /* Encoding options */
-       
+
        boost::shared_ptr<HasSampleFormat> hsf;
-       
-       if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (ptr)) {
-               hsf->SampleFormatSelectChanged.connect (sigc::mem_fun (*this, &ExportFormatManager::change_sample_format_selection));
-               hsf->DitherTypeSelectChanged.connect (sigc::mem_fun (*this, &ExportFormatManager::change_dither_type_selection));
+
+       if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (ptr))) {
+               hsf->SampleFormatSelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_sample_format_selection, this, _1, _2));
+               hsf->DitherTypeSelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_dither_type_selection, this, _1, _2));
        }
 }
 
 void
 ExportFormatManager::add_sample_rate (SampleRatePtr ptr)
 {
-       ptr->SelectChanged.connect (sigc::bind (sigc::mem_fun (*this, &ExportFormatManager::change_sample_rate_selection), WeakSampleRatePtr (ptr)));
+       ptr->SelectChanged.connect_same_thread (*this, boost::bind (&ExportFormatManager::change_sample_rate_selection, this, _1, WeakSampleRatePtr (ptr)));
        sample_rates.push_back (ptr);
 }
 
 void
-ExportFormatManager::set_name (Glib::ustring name)
+ExportFormatManager::set_name (string name)
 {
        current_selection->set_name (name);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_src_quality (ExportFormatBase::SRCQuality value)
 {
        current_selection->set_src_quality (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::select_with_cue (bool value)
+{
+       current_selection->set_with_cue (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::select_with_toc (bool value)
+{
+       current_selection->set_with_toc (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::select_with_mp4chaps (bool value)
+{
+       current_selection->set_with_mp4chaps (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::set_command (std::string command)
+{
+       current_selection->set_command (command);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_trim_beginning (bool value)
 {
        current_selection->set_trim_beginning (value);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_silence_beginning (AnyTime const & time)
 {
        current_selection->set_silence_beginning (time);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_trim_end (bool value)
 {
        current_selection->set_trim_end (value);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_silence_end (AnyTime const & time)
 {
        current_selection->set_silence_end (time);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_normalize (bool value)
 {
        current_selection->set_normalize (value);
+       check_for_description_change ();
 }
 
 void
-ExportFormatManager::select_normalize_target (float value)
+ExportFormatManager::select_normalize_loudness (bool value)
 {
-       current_selection->set_normalize_target (value);
+       current_selection->set_normalize_loudness (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::select_normalize_dbfs (float value)
+{
+       current_selection->set_normalize_dbfs (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::select_normalize_lufs (float value)
+{
+       current_selection->set_normalize_lufs (value);
+       check_for_description_change ();
+}
+
+void
+ExportFormatManager::select_normalize_dbtp (float value)
+{
+       current_selection->set_normalize_dbtp (value);
+       check_for_description_change ();
 }
 
 void
 ExportFormatManager::select_tagging (bool tag)
 {
        current_selection->set_tag (tag);
+       check_for_description_change ();
 }
 
 void
-ExportFormatManager::change_compatibility_selection (bool select, WeakCompatPtr const & compat)
+ExportFormatManager::change_compatibility_selection (bool select, WeakExportFormatCompatibilityPtr const & compat)
 {
        bool do_selection_changed = !pending_selection_change;
        if (!pending_selection_change) {
                pending_selection_change = true;
        }
 
-       CompatPtr ptr = compat.lock();
-       
+       ExportFormatCompatibilityPtr ptr = compat.lock();
+
        if (ptr && select) {
                select_compatibility (ptr);
        }
@@ -322,11 +400,11 @@ void
 ExportFormatManager::change_quality_selection (bool select, WeakQualityPtr const & quality)
 {
        QualityPtr ptr = quality.lock ();
-       
+
        if (!ptr) {
                return;
        }
-       
+
        if (select) {
                select_quality (ptr);
        } else if (ptr->quality == current_selection->quality()) {
@@ -336,14 +414,14 @@ ExportFormatManager::change_quality_selection (bool select, WeakQualityPtr const
 }
 
 void
-ExportFormatManager::change_format_selection (bool select, WeakFormatPtr const & format)
+ExportFormatManager::change_format_selection (bool select, WeakExportFormatPtr const & format)
 {
-       FormatPtr ptr = format.lock();
-       
+       ExportFormatPtr ptr = format.lock();
+
        if (!ptr) {
                return;
        }
-       
+
        if (select) {
                select_format (ptr);
        } else if (ptr->get_format_id() == current_selection->format_id()) {
@@ -356,11 +434,11 @@ void
 ExportFormatManager::change_sample_rate_selection (bool select, WeakSampleRatePtr const & rate)
 {
        SampleRatePtr ptr = rate.lock();
-       
+
        if (!ptr) {
                return;
        }
-       
+
        if (select) {
                select_sample_rate (ptr);
        } else if (ptr->rate == current_selection->sample_rate()) {
@@ -373,11 +451,11 @@ void
 ExportFormatManager::change_sample_format_selection (bool select, WeakSampleFormatPtr const & format)
 {
        SampleFormatPtr ptr = format.lock();
-       
+
        if (!ptr) {
                return;
        }
-       
+
        if (select) {
                select_sample_format (ptr);
        } else if (ptr->format == current_selection->sample_format()) {
@@ -390,11 +468,11 @@ void
 ExportFormatManager::change_dither_type_selection (bool select, WeakDitherTypePtr const & type)
 {
        DitherTypePtr ptr = type.lock();
-       
+
        if (!ptr) {
                return;
        }
-       
+
        if (select) {
                select_dither_type (ptr);
        } else if (ptr->type == current_selection->dither_type()) {
@@ -404,31 +482,31 @@ ExportFormatManager::change_dither_type_selection (bool select, WeakDitherTypePt
 }
 
 void
-ExportFormatManager::select_compatibility (WeakCompatPtr const & compat)
+ExportFormatManager::select_compatibility (WeakExportFormatCompatibilityPtr const & /*compat*/)
 {
        /* Calculate compatibility intersection for the selection */
-       
-       FormatBasePtr compat_intersect = get_compatibility_intersection ();
-       
+
+       ExportFormatBasePtr compat_intersect = get_compatibility_intersection ();
+
        /* Unselect incompatible items */
-       
+
        boost::shared_ptr<ExportFormatBase> select_intersect;
-       
+
        select_intersect = compat_intersect->get_intersection (*current_selection);
        if (select_intersect->qualities_empty()) {
                select_quality (QualityPtr());
        }
-       
+
        select_intersect = compat_intersect->get_intersection (*current_selection);
        if (select_intersect->formats_empty()) {
-               select_format (FormatPtr());
+               select_format (ExportFormatPtr());
        }
-       
+
        select_intersect = compat_intersect->get_intersection (*current_selection);
        if (select_intersect->sample_rates_empty()) {
                select_sample_rate (SampleRatePtr());
        }
-       
+
        select_intersect = compat_intersect->get_intersection (*current_selection);
        if (select_intersect->sample_formats_empty()) {
                select_sample_format (SampleFormatPtr());
@@ -445,36 +523,36 @@ ExportFormatManager::select_quality (QualityPtr const & quality)
 
        if (quality) {
                current_selection->set_quality (quality->quality);
-               
+
                /* Deselect format if it is incompatible */
-       
-               FormatPtr format = get_selected_format();
+
+               ExportFormatPtr format = get_selected_format();
                if (format && !format->has_quality (quality->quality)) {
                        format->set_selected (false);
                }
-               
+
        } else {
                current_selection->set_quality (ExportFormatBase::Q_None);
-               
+
                QualityPtr current_quality = get_selected_quality();
                if (current_quality) {
                        current_quality->set_selected (false);
                }
-               
+
                /* Note:
                 * A quality is never explicitly deselected without also deselecting the format
                 * so we don't need to deselect the format here.
                 * doing so causes extra complications
                 */
        }
-       
+
        if (do_selection_changed) {
                selection_changed ();
        }
 }
 
 void
-ExportFormatManager::select_format (FormatPtr const & format)
+ExportFormatManager::select_format (ExportFormatPtr const & format)
 {
        bool do_selection_changed = !pending_selection_change;
        if (!pending_selection_change) {
@@ -484,9 +562,9 @@ ExportFormatManager::select_format (FormatPtr const & format)
        current_selection->set_format (format);
 
        if (format) {
-               
+
                /* Slect right quality for format */
-       
+
                ExportFormatBase::Quality quality = format->get_quality();
                for (QualityList::iterator it = qualities.begin (); it != qualities.end (); ++it) {
                        if ((*it)->quality == quality) {
@@ -495,16 +573,16 @@ ExportFormatManager::select_format (FormatPtr const & format)
                                (*it)->set_selected (false);
                        }
                }
-               
+
                /* Handle sample formats */
-               
+
                ExportFormatBase::SampleFormat format_to_select;
                if (format->sample_format_is_compatible (current_selection->sample_format())) {
                        format_to_select = current_selection->sample_format();
                } else {
                        format_to_select = format->default_sample_format();
                }
-               
+
                boost::shared_ptr<HasSampleFormat> hsf;
                if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (format))) {
                        SampleFormatList sample_formats = hsf->get_sample_formats();
@@ -516,16 +594,16 @@ ExportFormatManager::select_format (FormatPtr const & format)
                                }
                        }
                }
-               
+
                current_selection->set_sample_format (format_to_select);
-               
+
        } else {
-               FormatPtr current_format = get_selected_format ();
+               ExportFormatPtr current_format = get_selected_format ();
                if (current_format) {
                        current_format->set_selected (false);
                }
        }
-       
+
        if (do_selection_changed) {
                selection_changed ();
        }
@@ -544,13 +622,13 @@ ExportFormatManager::select_sample_rate (SampleRatePtr const & rate)
                current_selection->set_sample_rate (rate->rate);
        } else {
                current_selection->set_sample_rate (ExportFormatBase::SR_None);
-               
+
                SampleRatePtr current_rate = get_selected_sample_rate();
                if (current_rate) {
                        current_rate->set_selected (false);
                }
        }
-       
+
        if (do_selection_changed) {
                selection_changed ();
        }
@@ -569,13 +647,13 @@ ExportFormatManager::select_sample_format (SampleFormatPtr const & format)
                current_selection->set_sample_format (format->format);
        } else {
                current_selection->set_sample_format (ExportFormatBase::SF_None);
-               
+
                SampleFormatPtr current_format = get_selected_sample_format();
                if (current_format) {
                        current_format->set_selected (false);
                }
        }
-       
+
        if (do_selection_changed) {
                selection_changed ();
        }
@@ -595,7 +673,7 @@ ExportFormatManager::select_dither_type (DitherTypePtr const & type)
        } else {
                current_selection->set_dither_type (ExportFormatBase::D_None);
        }
-       
+
        if (do_selection_changed) {
                selection_changed ();
        }
@@ -605,46 +683,46 @@ void
 ExportFormatManager::selection_changed ()
 {
        /* Get a list of incompatible compatibility selections */
-       
+
        CompatList incompatibles;
        for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
                if (!current_selection->is_compatible_with (**it)) {
                        incompatibles.push_back (*it);
                }
        }
-       
+
        /* Deselect them */
-       
+
        for (CompatList::iterator it = incompatibles.begin(); it != incompatibles.end(); ++it) {
                (*it)->set_selected (false);
        }
-       
+
        /* Mark compatibility for everything necessary */
-       
+
        std::set<ExportFormatBase::Quality> compatible_qualities;
-       FormatBasePtr compat_intersect = get_compatibility_intersection ();
+       ExportFormatBasePtr compat_intersect = get_compatibility_intersection ();
        ExportFormatCompatibility global_compat (*compat_intersect);
-       
+
        for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
                if ((*it)->set_compatibility_state (global_compat)) {
                        compatible_qualities.insert ((*it)->get_quality());
                }
        }
-       
+
        bool any_quality_compatible = true;
        for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
                if (compatible_qualities.find((*it)->quality) != compatible_qualities.end()) {
                        (*it)->set_compatible (true);
-                       
+
                } else {
                        (*it)->set_compatible (false);
-                       
+
                        if ((*it)->quality != ExportFormatBase::Q_Any) {
                                any_quality_compatible = false;
                        }
                }
        }
-       
+
        if (any_quality_compatible) {
                for (QualityList::iterator it = qualities.begin(); it != qualities.end(); ++it) {
                        if ((*it)->quality == ExportFormatBase::Q_Any) {
@@ -653,7 +731,7 @@ ExportFormatManager::selection_changed ()
                        }
                }
        }
-       
+
        for (SampleRateList::iterator it = sample_rates.begin(); it != sample_rates.end(); ++it) {
                if (compat_intersect->has_sample_rate ((*it)->rate)) {
                        (*it)->set_compatible (true);
@@ -661,10 +739,10 @@ ExportFormatManager::selection_changed ()
                        (*it)->set_compatible (false);
                }
        }
-       
+
        boost::shared_ptr<HasSampleFormat> hsf;
-       if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format())) {
-       
+       if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format()))) {
+
                SampleFormatList sf_list = hsf->get_sample_formats();
                for (SampleFormatList::iterator it = sf_list.begin(); it != sf_list.end(); ++it) {
                        if (compat_intersect->has_sample_format ((*it)->format)) {
@@ -673,18 +751,29 @@ ExportFormatManager::selection_changed ()
                                (*it)->set_compatible (false);
                        }
                }
-       
+
        }
-       
-       /* Signal completeness */
-       
+
+       /* Signal completeness and possible description change */
+
        CompleteChanged (current_selection->is_complete());
-       
+       check_for_description_change ();
+
        /* Reset pending state */
-       
+
        pending_selection_change = false;
 }
 
+void
+ExportFormatManager::check_for_description_change ()
+{
+       std::string new_description = current_selection->description();
+       if (new_description == prev_description) { return; }
+
+       prev_description = new_description;
+       DescriptionChanged();
+}
+
 ExportFormatManager::QualityPtr
 ExportFormatManager::get_selected_quality ()
 {
@@ -693,21 +782,21 @@ ExportFormatManager::get_selected_quality ()
                        return *it;
                }
        }
-       
+
        return QualityPtr();
 }
 
-ExportFormatManager::FormatPtr
+ExportFormatPtr
 ExportFormatManager::get_selected_format ()
 {
-       FormatPtr format;
+       ExportFormatPtr format;
 
        for (FormatList::iterator it = formats.begin(); it != formats.end(); ++it) {
                if ((*it)->selected()) {
                        return *it;
                }
        }
-       
+
        return format;
 }
 
@@ -719,7 +808,7 @@ ExportFormatManager::get_selected_sample_rate ()
                        return *it;
                }
        }
-       
+
        return SampleRatePtr();
 }
 
@@ -727,8 +816,8 @@ ExportFormatManager::SampleFormatPtr
 ExportFormatManager::get_selected_sample_format ()
 {
        boost::shared_ptr<HasSampleFormat> hsf;
-       
-       if (hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format())) {
+
+       if ((hsf = boost::dynamic_pointer_cast<HasSampleFormat> (get_selected_format()))) {
                return hsf->get_selected_sample_format ();
        } else {
                return SampleFormatPtr ();
@@ -736,17 +825,17 @@ ExportFormatManager::get_selected_sample_format ()
 }
 
 
-ExportFormatManager::FormatBasePtr
+ExportFormatBasePtr
 ExportFormatManager::get_compatibility_intersection ()
 {
-       FormatBasePtr compat_intersect = universal_set;
-       
+       ExportFormatBasePtr compat_intersect = universal_set;
+
        for (CompatList::iterator it = compatibilities.begin(); it != compatibilities.end(); ++it) {
                if ((*it)->selected ()) {
                        compat_intersect = compat_intersect->get_intersection (**it);
                }
        }
-       
+
        return compat_intersect;
 }