/* * Copyright (C) 2022 Robin Gareus * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "pbd/openuri.h" #include "ardour/export_channel_configuration.h" #include "ardour/export_filename.h" #include "ardour/export_preset.h" #include "ardour/export_profile_manager.h" #include "ardour/export_status.h" #include "ardour/export_timespan.h" #include "ardour/profile.h" #include "ardour/session_directory.h" #include "nag.h" #include "simple_export_dialog.h" #include "pbd/i18n.h" using namespace std; using namespace ARDOUR; using namespace PBD; using namespace Gtk; SimpleExportDialog::SimpleExportDialog (PublicEditor& editor) : ARDOUR::SimpleExport () , ArdourDialog (_("Quick Audio Export"), true, false) , _editor (editor) , _eps (true) { if (_eps.the_combo ().get_parent ()) { _eps.the_combo ().get_parent ()->remove (_eps.the_combo ()); } Table* t = manage (new Table); int r = 0; t->set_spacings (4); #define LBL(TXT) *manage (new Label (_(TXT), ALIGN_END)) /* clang-format off */ t->attach (LBL ("Format preset:"), 0, 1, r, r + 1, FILL, SHRINK, 0, 0); t->attach (_eps.the_combo (), 1, 2, r, r + 1, EXPAND, SHRINK, 0, 0); ++r; t->attach (LBL ("Export range:"), 0, 1, r, r + 1, FILL, SHRINK, 0, 0); t->attach (_range_combo, 1, 2, r, r + 1, EXPAND | FILL, SHRINK, 0, 0); ++r; t->attach (LBL ("After export:"), 0, 1, r, r + 1, FILL, SHRINK, 0, 0); t->attach (_post_export_combo, 1, 2, r, r + 1, EXPAND | FILL, SHRINK, 0, 0); ++r; t->attach (_error_label, 0, 2, r, r + 1, EXPAND | FILL, SHRINK, 0, 0); ++r; t->attach (_progress_bar, 0, 2, r, r + 1, EXPAND | FILL, SHRINK, 0, 0); /* clang-format on */ #undef LBL _post_export_combo.append (_("open the folder where files are exported to.")); _post_export_combo.append (_("do nothing.")); _post_export_combo.set_active (0); get_vbox ()->pack_start (*t, false, false); _cancel_button = add_button (Gtk::Stock::CANCEL, RESPONSE_CANCEL); _export_button = add_button (_("Export"), RESPONSE_OK); _cancel_button->signal_clicked ().connect (sigc::mem_fun (*this, &SimpleExportDialog::close_dialog)); _export_button->signal_clicked ().connect (sigc::mem_fun (*this, &SimpleExportDialog::start_export)); _progress_bar.set_no_show_all (true); _error_label.set_no_show_all (true); _export_button->set_sensitive (false); _range_combo.set_sensitive (false); t->show_all (); } XMLNode& SimpleExportDialog::get_state () const { XMLNode* node = new XMLNode (X_("QuickExport")); node->set_property (X_("PresetUUID"), preset_uuid ()); node->set_property (X_("PostExport"), _post_export_combo.get_active_row_number ()); return *node; } void SimpleExportDialog::set_state (XMLNode const& node) { int post_export; std::string pset_uuid; if (node.get_property (X_("PresetUUID"), pset_uuid)) { set_preset (pset_uuid); } if (node.get_property (X_("PostExport"), post_export)) { _post_export_combo.set_active (post_export); } } void SimpleExportDialog::set_session (ARDOUR::Session* s) { SimpleExport::set_session (s); ArdourDialog::set_session (s); _range_combo.remove_all (); if (!s) { _export_button->set_sensitive (false); _range_combo.set_sensitive (false); return; } XMLNode* node = s->extra_xml (X_("QuickExport")); if (node) { set_state (*node); } _eps.set_manager (_manager); if (!check_outputs ()) { set_error ("Error: Session has no master-bus"); return; } /* check range */ Location* srl (s->locations ()->session_range_location ()); TimeSelection const& tsel (_editor.get_selection ().time); bool ok = false; if (!tsel.empty ()) { ok = true; _range_combo.append (_("using time selection.")); } if (srl) { ok = true; _range_combo.append (_("from session start marker to session end marker.")); // same text as ExportVideoDialog::apply_state } if (!ok) { set_error ("Error: No valid range to export. Select a range or create session start/end markers"); return; } _range_combo.set_active (0); _range_combo.set_sensitive (true); _export_button->set_sensitive (true); } void SimpleExportDialog::set_error (std::string const& err) { _export_button->set_sensitive (false); _range_combo.set_sensitive (false); _error_label.set_text (err); _error_label.show (); } void SimpleExportDialog::close_dialog () { if (_status->running ()) { _status->abort (); } } void SimpleExportDialog::start_export () { Location* srl = SimpleExport::_session->locations ()->session_range_location (); TimeSelection const& tsel (_editor.get_selection ().time); std::string range = _range_combo.get_active_text (); if (!tsel.empty () && range == _("using time selection.")) { set_range (tsel.start_sample (), tsel.end_sample ()); SimpleExport::set_name (string_compose (_("%1 (selection)"), SimpleExport::_session->snap_name ())); } else { set_range (srl->start_sample (), srl->end_sample ()); SimpleExport::set_name (SimpleExport::_session->snap_name ()); } SimpleExport::_session->add_extra_xml (get_state ()); _cancel_button->set_label (_("Stop Export")); _export_button->set_sensitive (false); _progress_bar.set_fraction (0.0); _progress_bar.show (); #if 0 _eps.hide (); _range_combo.hide (); _post_export_combo,.hide (); #endif _progress_connection = Glib::signal_timeout ().connect (sigc::mem_fun (*this, &SimpleExportDialog::progress_timeout), 100); if (run_export ()) { hide (); if (_post_export_combo.get_active_row_number () == 0) { PBD::open_folder (folder ()); } if (!ARDOUR::Profile->get_mixbus ()) { NagScreen* ns = NagScreen::maybe_nag (_("export")); if (ns) { ns->nag (); delete ns; } } } else if (!_status->aborted ()) { hide (); std::string txt = _("Export has been aborted due to an error!\nSee the Log for details."); Gtk::MessageDialog msg (txt, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); msg.run (); } } bool SimpleExportDialog::progress_timeout () { std::string status_text; float progress = -1; switch (_status->active_job) { case ExportStatus::Exporting: status_text = string_compose (_("Exporting '%3' (timespan %1 of %2)"), _status->timespan, _status->total_timespans, _status->timespan_name); progress = ((float)_status->processed_samples_current_timespan) / _status->total_samples_current_timespan; break; case ExportStatus::Normalizing: status_text = string_compose (_("Normalizing '%3' (timespan %1 of %2)"), _status->timespan, _status->total_timespans, _status->timespan_name); progress = ((float)_status->current_postprocessing_cycle) / _status->total_postprocessing_cycles; break; case ExportStatus::Encoding: status_text = string_compose (_("Encoding '%3' (timespan %1 of %2)"), _status->timespan, _status->total_timespans, _status->timespan_name); progress = ((float)_status->current_postprocessing_cycle) / _status->total_postprocessing_cycles; break; case ExportStatus::Tagging: status_text = string_compose (_("Tagging '%3' (timespan %1 of %2)"), _status->timespan, _status->total_timespans, _status->timespan_name); case ExportStatus::Uploading: break; case ExportStatus::Command: status_text = string_compose (_("Running Post Export Command for '%1'"), _status->timespan_name); break; } _progress_bar.set_text (status_text); if (progress >= 0) { _progress_bar.set_fraction (progress); } else { _progress_bar.set_pulse_step (.1); _progress_bar.pulse (); } return true; }