Tim Mayberry
078889efa8
I used the Widget::on_hide method in the ExportFileDialog to defer the saving of changes in state of the analysis and soundcloud-upload checkboxes as it was not possible to save the format xml state directly from the ToggleButton::toggled() signal as it created a recursive loop and also to prevent saving the state more than once. Even though the ExportProfileManager::FormatListChanged signal is no longer emitted when saving format state and the crash no longer occurs without this change. I think it is worth saving explicitily from in the toggle callbacks to reduce the complexity of understanding what is taking place and when even if it is less efficient. There is definitely more opportunity for refactoring and redesign.
362 lines
11 KiB
C++
362 lines
11 KiB
C++
/*
|
|
Copyright (C) 2008 Paul Davis
|
|
Author: Sakari Bergen
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#include "export_file_notebook.h"
|
|
|
|
#include "ardour/export_format_specification.h"
|
|
|
|
#include "gui_thread.h"
|
|
#include "utils.h"
|
|
#include "pbd/i18n.h"
|
|
|
|
using namespace ARDOUR;
|
|
using namespace ARDOUR_UI_UTILS;
|
|
using namespace PBD;
|
|
|
|
ExportFileNotebook::ExportFileNotebook () :
|
|
page_counter (1)
|
|
{
|
|
/* Last page */
|
|
|
|
new_file_button.set_image (*Gtk::manage (new Gtk::Image (::get_icon("add"))));
|
|
new_file_button.set_label (_("Add another format"));
|
|
new_file_button.set_alignment (0, 0.5);
|
|
new_file_button.set_relief (Gtk::RELIEF_NONE);
|
|
|
|
new_file_hbox.pack_start (new_file_button, true, true);
|
|
append_page (new_file_dummy, new_file_hbox);
|
|
set_tab_label_packing (new_file_dummy, true, true, Gtk::PACK_START);
|
|
new_file_hbox.show_all_children ();
|
|
|
|
page_change_connection = signal_switch_page().connect (sigc::mem_fun (*this, &ExportFileNotebook::handle_page_change));
|
|
new_file_button.signal_clicked().connect (sigc::mem_fun (*this, &ExportFileNotebook::add_new_file_page));
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::set_session_and_manager (ARDOUR::Session * s, boost::shared_ptr<ARDOUR::ExportProfileManager> manager)
|
|
{
|
|
SessionHandlePtr::set_session (s);
|
|
profile_manager = manager;
|
|
|
|
sync_with_manager ();
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::sync_with_manager ()
|
|
{
|
|
/* Clear pages from notebook
|
|
The page switch handling has to be disabled during removing all pages due to a gtk bug
|
|
*/
|
|
|
|
page_change_connection.block();
|
|
while (get_n_pages() > 1) {
|
|
remove_page (0);
|
|
}
|
|
page_change_connection.block(false);
|
|
|
|
page_counter = 1;
|
|
last_visible_page = 0;
|
|
|
|
/* File notebook */
|
|
|
|
ExportProfileManager::FormatStateList const & formats = profile_manager->get_formats ();
|
|
ExportProfileManager::FormatStateList::const_iterator format_it;
|
|
ExportProfileManager::FilenameStateList const & filenames = profile_manager->get_filenames ();
|
|
ExportProfileManager::FilenameStateList::const_iterator filename_it;
|
|
for (format_it = formats.begin(), filename_it = filenames.begin();
|
|
format_it != formats.end() && filename_it != filenames.end();
|
|
++format_it, ++filename_it) {
|
|
add_file_page (*format_it, *filename_it);
|
|
}
|
|
|
|
set_current_page (0);
|
|
update_soundcloud_upload ();
|
|
CriticalSelectionChanged ();
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::update_soundcloud_upload ()
|
|
{
|
|
int i;
|
|
bool show_credentials_entry = false;
|
|
ExportProfileManager::FormatStateList const & formats = profile_manager->get_formats ();
|
|
ExportProfileManager::FormatStateList::const_iterator format_it;
|
|
|
|
for (i = 0, format_it = formats.begin(); format_it != formats.end(); ++i, ++format_it) {
|
|
FilePage * page;
|
|
if ((page = dynamic_cast<FilePage *> (get_nth_page (i)))) {
|
|
bool this_soundcloud_upload = page->get_soundcloud_upload ();
|
|
(*format_it)->format->set_soundcloud_upload (this_soundcloud_upload);
|
|
if (this_soundcloud_upload) {
|
|
show_credentials_entry = true;
|
|
}
|
|
}
|
|
}
|
|
soundcloud_export_selector->set_visible (show_credentials_entry);
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::analysis_changed ()
|
|
{
|
|
format_state->format->set_analyse (analysis_button.get_active ());
|
|
profile_manager->save_format_to_disk (format_state->format);
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::update_analysis_button ()
|
|
{
|
|
analysis_button.set_active (format_state->format->analyse());
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::update_example_filenames ()
|
|
{
|
|
int i = 0;
|
|
FilePage * page;
|
|
while ((page = dynamic_cast<FilePage *> (get_nth_page (i++)))) {
|
|
page->update_example_filename();
|
|
}
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::add_new_file_page ()
|
|
{
|
|
FilePage * page;
|
|
if ((page = dynamic_cast<FilePage *> (get_nth_page (get_current_page())))) {
|
|
add_file_page (profile_manager->duplicate_format_state (page->get_format_state()),
|
|
profile_manager->duplicate_filename_state (page->get_filename_state()));
|
|
}
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::add_file_page (ARDOUR::ExportProfileManager::FormatStatePtr format_state, ARDOUR::ExportProfileManager::FilenameStatePtr filename_state)
|
|
{
|
|
FilePage * page = Gtk::manage (new FilePage (_session, profile_manager, this, page_counter, format_state, filename_state));
|
|
page->CriticalSelectionChanged.connect (CriticalSelectionChanged.make_slot());
|
|
insert_page (*page, page->get_tab_widget(), get_n_pages() - 1);
|
|
|
|
update_remove_file_page_sensitivity ();
|
|
show_all_children();
|
|
++page_counter;
|
|
|
|
CriticalSelectionChanged ();
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::remove_file_page (FilePage * page)
|
|
{
|
|
profile_manager->remove_format_state (page->get_format_state());
|
|
profile_manager->remove_filename_state (page->get_filename_state());
|
|
|
|
remove_page (*page);
|
|
update_remove_file_page_sensitivity ();
|
|
|
|
CriticalSelectionChanged ();
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::update_remove_file_page_sensitivity ()
|
|
{
|
|
FilePage * page;
|
|
if ((page = dynamic_cast<FilePage *> (get_nth_page (0)))) {
|
|
if (get_n_pages() > 2) {
|
|
page->set_remove_sensitive (true);
|
|
} else {
|
|
page->set_remove_sensitive (false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::handle_page_change (GtkNotebookPage*, uint32_t page)
|
|
{
|
|
if (page + 1 == (uint32_t) get_n_pages()) {
|
|
set_current_page (last_visible_page);
|
|
} else {
|
|
last_visible_page = page;
|
|
}
|
|
update_soundcloud_upload ();
|
|
}
|
|
|
|
ExportFileNotebook::FilePage::FilePage (Session * s, ManagerPtr profile_manager, ExportFileNotebook * parent, uint32_t number,
|
|
ExportProfileManager::FormatStatePtr format_state,
|
|
ExportProfileManager::FilenameStatePtr filename_state) :
|
|
format_state (format_state),
|
|
filename_state (filename_state),
|
|
profile_manager (profile_manager),
|
|
|
|
format_label (_("Format"), Gtk::ALIGN_LEFT),
|
|
filename_label (_("Location"), Gtk::ALIGN_LEFT),
|
|
soundcloud_upload_button (_("Upload to Soundcloud")),
|
|
analysis_button (_("Analyze Exported Audio")),
|
|
tab_number (number)
|
|
{
|
|
set_border_width (12);
|
|
|
|
pack_start (format_label, false, false, 0);
|
|
pack_start (format_align, false, false, 0);
|
|
pack_start (filename_label, false, false, 0);
|
|
pack_start (filename_align, false, false, 0);
|
|
|
|
Gtk::HBox *hbox = Gtk::manage (new Gtk::HBox());
|
|
hbox->set_spacing (6);
|
|
hbox->pack_start (soundcloud_upload_button, false, false, 0);
|
|
hbox->pack_start (analysis_button, false, false, 0);
|
|
pack_start (*hbox, false, false, 0);
|
|
|
|
format_align.add (format_selector);
|
|
format_align.set_padding (6, 12, 18, 0);
|
|
|
|
filename_align.add (filename_selector);
|
|
filename_align.set_padding (0, 12, 18, 0);
|
|
|
|
Pango::AttrList bold;
|
|
Pango::Attribute b = Pango::Attribute::create_attr_weight (Pango::WEIGHT_BOLD);
|
|
bold.insert (b);
|
|
|
|
format_label.set_attributes (bold);
|
|
filename_label.set_attributes (bold);
|
|
tab_label.set_attributes (bold);
|
|
|
|
/* Set states */
|
|
format_selector.set_state (format_state, s);
|
|
filename_selector.set_state (filename_state, s);
|
|
analysis_button.set_active (format_state->format->analyse());
|
|
soundcloud_upload_button.set_active (format_state->format->soundcloud_upload());
|
|
|
|
/* Signals */
|
|
|
|
tab_close_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*parent, &ExportFileNotebook::remove_file_page), this));
|
|
|
|
profile_manager->FormatListChanged.connect (format_connection, invalidator (*this), boost::bind (&ExportFormatSelector::update_format_list, &format_selector), gui_context());
|
|
|
|
format_selector.FormatEdited.connect (sigc::mem_fun (*this, &ExportFileNotebook::FilePage::save_format_to_manager));
|
|
format_selector.FormatRemoved.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::remove_format_profile));
|
|
format_selector.NewFormat.connect (sigc::mem_fun (*profile_manager, &ExportProfileManager::get_new_format));
|
|
|
|
format_selector.CriticalSelectionChanged.connect (
|
|
sigc::mem_fun (*this, &ExportFileNotebook::FilePage::critical_selection_changed));
|
|
filename_selector.CriticalSelectionChanged.connect (
|
|
sigc::mem_fun (*this, &ExportFileNotebook::FilePage::critical_selection_changed));
|
|
|
|
soundcloud_upload_button.signal_toggled().connect (sigc::mem_fun (*parent, &ExportFileNotebook::update_soundcloud_upload));
|
|
soundcloud_upload_button.signal_toggled().connect (sigc::mem_fun (*this, &ExportFileNotebook::FilePage::soundcloud_upload_changed));
|
|
analysis_button.signal_toggled().connect (sigc::mem_fun (*this, &ExportFileNotebook::FilePage::analysis_changed));
|
|
/* Tab widget */
|
|
|
|
tab_close_button.add (*Gtk::manage (new Gtk::Image (::get_icon("close"))));
|
|
tab_close_alignment.add (tab_close_button);
|
|
tab_close_alignment.set (0.5, 0.5, 0, 0);
|
|
|
|
tab_widget.pack_start (tab_label, false, false, 3);
|
|
tab_widget.pack_end (tab_close_alignment, false, false, 0);
|
|
tab_widget.show_all_children ();
|
|
update_tab_label ();
|
|
update_example_filename();
|
|
|
|
/* Done */
|
|
|
|
show_all_children ();
|
|
}
|
|
|
|
ExportFileNotebook::FilePage::~FilePage ()
|
|
{
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::set_remove_sensitive (bool value)
|
|
{
|
|
tab_close_button.set_sensitive (value);
|
|
}
|
|
|
|
std::string
|
|
ExportFileNotebook::FilePage::get_format_name () const
|
|
{
|
|
if (format_state && format_state->format) {
|
|
return format_state->format->name();
|
|
}
|
|
return _("No format!");
|
|
}
|
|
|
|
bool
|
|
ExportFileNotebook::FilePage::get_soundcloud_upload () const
|
|
{
|
|
return soundcloud_upload_button.get_active ();
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::soundcloud_upload_changed ()
|
|
{
|
|
profile_manager->save_format_to_disk (format_state->format);
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::update_soundcloud_upload_button ()
|
|
{
|
|
soundcloud_upload_button.set_active (format_state->format->soundcloud_upload());
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::save_format_to_manager (FormatPtr format)
|
|
{
|
|
profile_manager->save_format_to_disk (format);
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::update_tab_label ()
|
|
{
|
|
tab_label.set_text (string_compose (_("Format %1: %2"), tab_number, get_format_name()));
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::update_example_filename()
|
|
{
|
|
if (profile_manager) {
|
|
if (profile_manager->get_timespans().size() > 1
|
|
|| profile_manager->get_timespans().front()->timespans->size() > 1) {
|
|
filename_selector.require_timespan (true);
|
|
} else {
|
|
filename_selector.require_timespan (false);
|
|
}
|
|
|
|
std::string example;
|
|
if (format_state->format) {
|
|
example = profile_manager->get_sample_filename_for_format (
|
|
filename_state->filename, format_state->format);
|
|
}
|
|
|
|
if (example != "") {
|
|
filename_selector.set_example_filename(Glib::path_get_basename (example));
|
|
} else {
|
|
filename_selector.set_example_filename("");
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
ExportFileNotebook::FilePage::critical_selection_changed ()
|
|
{
|
|
update_tab_label();
|
|
update_example_filename();
|
|
update_analysis_button();
|
|
update_soundcloud_upload_button();
|
|
CriticalSelectionChanged();
|
|
}
|