Refactor ExportProjectDialog (#8215)

This refactors the export dialog to no longer use the export_project.ui file and moves it into standard C++ Qt code. This also brings minor changes to the dialog, such as horizontal labels instead of vertical ones.
This commit is contained in:
Sotonye Atemie
2026-01-22 19:07:25 -05:00
committed by GitHub
parent 64c346d513
commit 13ea2ee480
6 changed files with 299 additions and 680 deletions

View File

@@ -59,7 +59,8 @@ constexpr int BYTES_PER_FRAME = sizeof(SampleFrame);
constexpr float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000};
constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000};
constexpr auto SUPPORTED_BITRATES = std::array{64, 128, 160, 192, 256, 320};
class LMMS_EXPORT AudioEngine : public QObject
{

View File

@@ -27,45 +27,71 @@
#define LMMS_GUI_EXPORT_PROJECT_DIALOG_H
#include <QDialog>
#include <memory>
#include "ui_export_project.h"
#include "ProjectRenderer.h"
#include "RenderManager.h"
namespace lmms::gui
{
class QString;
class QLabel;
class QProgressBar;
class QCheckBox;
class QComboBox;
class QSpinBox;
class QFormLayout;
class QGroupBox;
namespace lmms::gui {
class ExportProjectDialog : public QDialog, public Ui::ExportProjectDialog
class ExportProjectDialog : public QDialog
{
Q_OBJECT
public:
ExportProjectDialog( const QString & _file_name, QWidget * _parent, bool multi_export );
enum class Mode
{
ExportProject,
ExportTracks,
};
protected:
void reject() override;
void closeEvent( QCloseEvent * _ce ) override;
private slots:
void startBtnClicked();
void updateTitleBar( int );
void accept() override;
void startExport();
void onFileFormatChanged(int);
ExportProjectDialog(const QString& path, Mode mode, QWidget* parent = nullptr);
private:
QString m_fileName;
QString m_dirName;
QString m_fileExtension;
bool m_multiExport;
void accept() override;
void reject() override;
void onFileFormatChanged(int index);
void onStartButtonClicked();
void updateTitleBar(int prog);
ProjectRenderer::ExportFileFormat m_ft;
QLabel* m_fileFormatLabel = nullptr;
QComboBox* m_fileFormatComboBox = nullptr;
QLabel* m_sampleRateLabel = nullptr;
QComboBox* m_sampleRateComboBox = nullptr;
QLabel* m_bitRateLabel = nullptr;
QComboBox* m_bitRateComboBox = nullptr;
QLabel* m_bitDepthLabel = nullptr;
QComboBox* m_bitDepthComboBox = nullptr;
QLabel* m_stereoModeLabel = nullptr;
QComboBox* m_stereoModeComboBox = nullptr;
QLabel* m_compressionLevelLabel = nullptr;
QComboBox* m_compressionLevelComboBox = nullptr;
QGroupBox* m_fileFormatSettingsGroupBox = nullptr;
QFormLayout* m_fileFormatSettingsLayout = nullptr;
QCheckBox* m_exportAsLoopBox = nullptr;
QCheckBox* m_exportBetweenLoopMarkersBox = nullptr;
QLabel* m_loopRepeatLabel = nullptr;
QSpinBox* m_loopRepeatBox = nullptr;
QPushButton* m_startButton = nullptr;
QPushButton* m_cancelButton = nullptr;
QProgressBar* m_progressBar = nullptr;
QString m_path;
Mode m_mode;
std::unique_ptr<RenderManager> m_renderManager;
} ;
};
} // namespace lmms::gui

View File

@@ -39,14 +39,16 @@ public:
{
Depth16Bit,
Depth24Bit,
Depth32Bit
Depth32Bit,
Count
};
enum class StereoMode
{
Mono,
Stereo,
JointStereo,
Mono
Count
};
public:

View File

@@ -1505,7 +1505,9 @@ void MainWindow::exportProject(bool multiExport)
}
}
ExportProjectDialog epd( exportFileName, getGUI()->mainWindow(), multiExport );
ExportProjectDialog epd(exportFileName,
multiExport ? ExportProjectDialog::Mode::ExportTracks : ExportProjectDialog::Mode::ExportProject,
getGUI()->mainWindow());
epd.exec();
}
}

View File

@@ -22,274 +22,279 @@
*
*/
#include <QFileInfo>
#include <QMessageBox>
#include "ExportProjectDialog.h"
#include <QCheckBox>
#include <QComboBox>
#include <QDir>
#include <QFileInfo>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QProgressBar>
#include <QPushButton>
#include <QSpinBox>
#include <QVBoxLayout>
#include "Engine.h"
#include "ProjectRenderer.h"
#include "Song.h"
#include "GuiApplication.h"
#include "MainWindow.h"
#include "OutputSettings.h"
namespace lmms::gui
namespace lmms::gui {
namespace {
constexpr auto maxCompressionLevel = 8;
constexpr auto defaultCompressionLevel = 5;
constexpr auto defaultBitRate = SUPPORTED_BITRATES[2];
constexpr auto defaultBitDepth = OutputSettings::BitDepth::Depth24Bit;
constexpr auto defaultStereoMode = OutputSettings::StereoMode::Stereo;
constexpr auto maxLoopRepeat = std::numeric_limits<int>::max();
} // namespace
ExportProjectDialog::ExportProjectDialog(const QString& path, Mode mode, QWidget* parent)
: QDialog(parent)
, m_fileFormatLabel(new QLabel(tr("File format:")))
, m_fileFormatComboBox(new QComboBox())
, m_sampleRateLabel(new QLabel(tr("Sampling rate:")))
, m_sampleRateComboBox(new QComboBox())
, m_bitRateLabel(new QLabel(tr("Bit rate:")))
, m_bitRateComboBox(new QComboBox())
, m_bitDepthLabel(new QLabel(tr("Bit depth:")))
, m_bitDepthComboBox(new QComboBox())
, m_stereoModeLabel(new QLabel(("Stereo mode:")))
, m_stereoModeComboBox(new QComboBox())
, m_compressionLevelLabel(new QLabel(tr("Compression level:")))
, m_compressionLevelComboBox(new QComboBox())
, m_fileFormatSettingsGroupBox(new QGroupBox(tr("File format settings")))
, m_fileFormatSettingsLayout(new QFormLayout(m_fileFormatSettingsGroupBox))
, m_exportAsLoopBox(new QCheckBox(tr("Export as loop (remove extra bar)")))
, m_exportBetweenLoopMarkersBox(new QCheckBox(tr("Export between loop markers")))
, m_loopRepeatLabel(new QLabel(tr("Render looped section:")))
, m_loopRepeatBox(new QSpinBox())
, m_startButton(new QPushButton(tr("Start")))
, m_cancelButton(new QPushButton(tr("Cancel")))
, m_progressBar(new QProgressBar())
, m_path(path)
, m_mode(mode)
{
setWindowTitle(tr("Export project"));
ExportProjectDialog::ExportProjectDialog( const QString & _file_name,
QWidget * _parent, bool multi_export=false ) :
QDialog( _parent ),
Ui::ExportProjectDialog(),
m_fileName( _file_name ),
m_fileExtension(),
m_multiExport( multi_export ),
m_renderManager( nullptr )
{
setupUi( this );
setWindowTitle( tr( "Export project to %1" ).arg(
QFileInfo( _file_name ).fileName() ) );
// Get the extension of the chosen file.
QStringList parts = _file_name.split( '.' );
QString fileExt;
if( parts.size() > 0 )
for (const auto& device : ProjectRenderer::fileEncodeDevices)
{
fileExt = "." + parts[parts.size()-1];
if (!device.isAvailable()) { continue; }
m_fileFormatComboBox->addItem(tr(device.m_description), static_cast<int>(device.m_fileFormat));
}
int cbIndex = 0;
for (auto i = std::size_t{0}; i < ProjectRenderer::NumFileFormats; ++i)
for (const auto& sampleRate : SUPPORTED_SAMPLERATES)
{
if( ProjectRenderer::fileEncodeDevices[i].isAvailable() )
const auto str = tr("%1 %2").arg(QString::number(sampleRate), "Hz");
m_sampleRateComboBox->addItem(str, sampleRate);
}
for (const auto& bitRate : SUPPORTED_BITRATES)
{
const auto str = tr("%1 %2").arg(QString::number(bitRate), "KBit/s");
m_bitRateComboBox->addItem(str, bitRate);
}
for (auto i = 0; i < static_cast<int>(OutputSettings::BitDepth::Count); ++i)
{
switch (static_cast<OutputSettings::BitDepth>(i))
{
// Get the extension of this format.
QString renderExt = ProjectRenderer::fileEncodeDevices[i].m_extension;
// Add to combo box.
fileFormatCB->addItem( ProjectRenderer::tr(
ProjectRenderer::fileEncodeDevices[i].m_description ),
QVariant( static_cast<int>(ProjectRenderer::fileEncodeDevices[i].m_fileFormat) ) // Format tag; later used for identification.
);
// If this is our extension, select it.
if( QString::compare( renderExt, fileExt,
Qt::CaseInsensitive ) == 0 )
{
fileFormatCB->setCurrentIndex( cbIndex );
}
cbIndex++;
case OutputSettings::BitDepth::Depth16Bit:
m_bitDepthComboBox->addItem(tr("16 Bit integer"), i);
break;
case OutputSettings::BitDepth::Depth24Bit:
m_bitDepthComboBox->addItem(tr("24 Bit integer"), i);
break;
case OutputSettings::BitDepth::Depth32Bit:
m_bitDepthComboBox->addItem(tr("32 Bit float"), i);
break;
default:
assert(false && "invalid or unsupported bit depth");
break;
}
}
int const MAX_LEVEL=8;
for(int i=0; i<=MAX_LEVEL; ++i)
for (auto i = 0; i < static_cast<int>(OutputSettings::StereoMode::Count); ++i)
{
QString info="";
if ( i==0 ){ info = tr( "( Fastest - biggest )" ); }
else if ( i==MAX_LEVEL ){ info = tr( "( Slowest - smallest )" ); }
compLevelCB->addItem(
QString::number(i)+" "+info,
QVariant(i/static_cast<double>(MAX_LEVEL))
);
}
compLevelCB->setCurrentIndex(5);
#ifndef LMMS_HAVE_SF_COMPLEVEL
// Disable this widget; the setting would be ignored by the renderer.
compressionWidget->setVisible(false);
#endif
for (const auto sampleRate : SUPPORTED_SAMPLERATES)
{
samplerateCB->addItem(tr("%1 Hz").arg(sampleRate), sampleRate);
switch (static_cast<OutputSettings::StereoMode>(i))
{
case OutputSettings::StereoMode::Mono:
m_stereoModeComboBox->addItem(tr("Mono"), i);
break;
case OutputSettings::StereoMode::Stereo:
m_stereoModeComboBox->addItem(tr("Stereo"), i);
break;
case OutputSettings::StereoMode::JointStereo:
m_stereoModeComboBox->addItem(tr("Joint stereo"), i);
break;
default:
assert(false && "invalid or unsupported stereo mode");
break;
}
}
const auto currentIndex = std::max(0, samplerateCB->findData(Engine::audioEngine()->outputSampleRate()));
samplerateCB->setCurrentIndex(currentIndex);
for (auto i = 0; i <= maxCompressionLevel; ++i)
{
const auto compressionValue = static_cast<float>(i) / maxCompressionLevel;
switch (i)
{
case 0:
m_compressionLevelComboBox->addItem(tr("%1 (Fastest, biggest)").arg(i), compressionValue);
break;
case maxCompressionLevel:
m_compressionLevelComboBox->addItem(tr("%1 (Slowest, smallest)").arg(i), compressionValue);
break;
default:
m_compressionLevelComboBox->addItem(QString::number(i), compressionValue);
break;
}
}
connect( startButton, SIGNAL(clicked()),
this, SLOT(startBtnClicked()));
auto loopRepeatLayout = new QHBoxLayout{};
loopRepeatLayout->addWidget(m_loopRepeatLabel);
loopRepeatLayout->addWidget(m_loopRepeatBox);
auto exportSettingsGroupBox = new QGroupBox(tr("Export settings"));
auto exportSettingsLayout = new QVBoxLayout{exportSettingsGroupBox};
exportSettingsLayout->addWidget(m_exportAsLoopBox);
exportSettingsLayout->addWidget(m_exportBetweenLoopMarkersBox);
exportSettingsLayout->addLayout(loopRepeatLayout);
m_fileFormatSettingsLayout->addRow(m_fileFormatLabel, m_fileFormatComboBox);
auto startCancelButtonsLayout = new QHBoxLayout{};
startCancelButtonsLayout->addStretch();
startCancelButtonsLayout->addWidget(m_startButton);
startCancelButtonsLayout->addWidget(m_cancelButton);
auto mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(exportSettingsGroupBox);
mainLayout->addWidget(m_fileFormatSettingsGroupBox);
mainLayout->addStretch();
mainLayout->addLayout(startCancelButtonsLayout);
mainLayout->addWidget(m_progressBar);
m_progressBar->setValue(0);
m_loopRepeatBox->setRange(1, maxLoopRepeat);
m_loopRepeatBox->setValue(1);
m_loopRepeatBox->setSuffix(tr(" time(s)"));
m_fileFormatComboBox->setCurrentIndex(-1);
connect(m_fileFormatComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ExportProjectDialog::onFileFormatChanged);
if (mode == Mode::ExportProject)
{
const auto pathExtension = QFileInfo{path}.completeSuffix().prepend(".");
const auto pathFormat = ProjectRenderer::getFileFormatFromExtension(pathExtension);
m_fileFormatComboBox->setCurrentIndex(
std::max(0, m_fileFormatComboBox->findData(static_cast<int>(pathFormat))));
}
m_bitRateComboBox->setCurrentIndex(std::max(0, m_bitRateComboBox->findData(defaultBitRate)));
m_bitDepthComboBox->setCurrentIndex(std::max(0, m_bitDepthComboBox->findData(static_cast<int>(defaultBitDepth))));
m_stereoModeComboBox->setCurrentIndex(
std::max(0, m_stereoModeComboBox->findData(static_cast<int>(defaultStereoMode))));
m_compressionLevelComboBox->setCurrentIndex(defaultCompressionLevel);
connect(m_startButton, &QPushButton::clicked, this, &ExportProjectDialog::onStartButtonClicked);
connect(m_cancelButton, &QPushButton::clicked, this, &ExportProjectDialog::reject);
}
void ExportProjectDialog::reject()
void ExportProjectDialog::onFileFormatChanged(int index)
{
if( m_renderManager ) {
m_renderManager->abortProcessing();
if (m_mode == Mode::ExportProject)
{
const auto fileInfo = QFileInfo{m_path};
const auto extension
= ProjectRenderer::getFileExtensionFromFormat(static_cast<ProjectRenderer::ExportFileFormat>(index));
m_path = fileInfo.path() + QDir::separator() + fileInfo.completeBaseName() + extension;
}
m_renderManager.reset(nullptr);
QDialog::reject();
// Remove and detach all rows after the file format row
while (m_fileFormatSettingsLayout->rowCount() > 1)
{
const auto& [label, field] = m_fileFormatSettingsLayout->takeRow(1);
label->widget()->setParent(nullptr);
field->widget()->setParent(nullptr);
}
switch (static_cast<ProjectRenderer::ExportFileFormat>(index))
{
case ProjectRenderer::ExportFileFormat::Wave:
m_fileFormatSettingsLayout->addRow(m_sampleRateLabel, m_sampleRateComboBox);
m_fileFormatSettingsLayout->addRow(m_bitDepthLabel, m_bitDepthComboBox);
break;
case ProjectRenderer::ExportFileFormat::Flac:
m_fileFormatSettingsLayout->addRow(m_sampleRateLabel, m_sampleRateComboBox);
m_fileFormatSettingsLayout->addRow(m_bitDepthLabel, m_bitDepthComboBox);
m_fileFormatSettingsLayout->addRow(m_compressionLevelLabel, m_compressionLevelComboBox);
break;
case ProjectRenderer::ExportFileFormat::Ogg:
m_fileFormatSettingsLayout->addRow(m_sampleRateLabel, m_sampleRateComboBox);
m_fileFormatSettingsLayout->addRow(m_bitRateLabel, m_bitRateComboBox);
break;
case ProjectRenderer::ExportFileFormat::MP3:
m_fileFormatSettingsLayout->addRow(m_stereoModeLabel, m_stereoModeComboBox);
m_fileFormatSettingsLayout->addRow(m_bitRateLabel, m_bitRateComboBox);
default:
break;
}
}
void ExportProjectDialog::onStartButtonClicked()
{
const auto sampleRate = static_cast<sample_rate_t>(m_sampleRateComboBox->currentData().toInt());
const auto bitRate = static_cast<bitrate_t>(m_bitRateComboBox->currentData().toInt());
const auto bitDepth = static_cast<OutputSettings::BitDepth>(m_bitDepthComboBox->currentData().toInt());
const auto stereoMode = static_cast<OutputSettings::StereoMode>(m_stereoModeComboBox->currentData().toInt());
auto outputSettings = OutputSettings{sampleRate, bitRate, bitDepth, stereoMode};
const auto compressionLevel = m_compressionLevelComboBox->currentData().toDouble();
outputSettings.setCompressionLevel(compressionLevel);
const auto format = static_cast<ProjectRenderer::ExportFileFormat>(m_fileFormatComboBox->currentData().toInt());
m_renderManager = std::make_unique<RenderManager>(outputSettings, format, m_path);
m_startButton->setEnabled(false);
Engine::getSong()->setExportLoop(m_exportAsLoopBox->isChecked());
Engine::getSong()->setRenderBetweenMarkers(m_exportBetweenLoopMarkersBox->isChecked());
Engine::getSong()->setLoopRenderCount(m_loopRepeatBox->value());
connect(m_renderManager.get(), &RenderManager::progressChanged, m_progressBar, &QProgressBar::setValue);
connect(m_renderManager.get(), &RenderManager::progressChanged, this, &ExportProjectDialog::updateTitleBar);
connect(m_renderManager.get(), &RenderManager::finished, this, &QDialog::accept);
switch (m_mode)
{
case Mode::ExportProject:
m_renderManager->renderProject();
break;
case Mode::ExportTracks:
m_renderManager->renderTracks();
break;
}
}
void ExportProjectDialog::accept()
{
m_renderManager.reset(nullptr);
QDialog::accept();
getGUI()->mainWindow()->resetWindowTitle();
}
void ExportProjectDialog::closeEvent( QCloseEvent * _ce )
void ExportProjectDialog::reject()
{
Engine::getSong()->setLoopRenderCount(1);
if( m_renderManager ) {
m_renderManager->abortProcessing();
}
QDialog::closeEvent( _ce );
if (m_renderManager) { m_renderManager->abortProcessing(); }
m_renderManager.reset(nullptr);
QDialog::reject();
}
OutputSettings::StereoMode mapToStereoMode(int index)
void ExportProjectDialog::updateTitleBar(int prog)
{
switch (index)
{
case 0:
return OutputSettings::StereoMode::Mono;
case 1:
return OutputSettings::StereoMode::Stereo;
case 2:
return OutputSettings::StereoMode::JointStereo;
default:
return OutputSettings::StereoMode::Stereo;
}
}
void ExportProjectDialog::startExport()
{
const auto bitrates = std::array{64, 128, 160, 192, 256, 320};
OutputSettings os = OutputSettings(samplerateCB->currentData().toInt(), bitrates[bitrateCB->currentIndex()],
static_cast<OutputSettings::BitDepth>(depthCB->currentIndex()),
mapToStereoMode(stereoModeComboBox->currentIndex()));
if (compressionWidget->isVisible())
{
double level = compLevelCB->itemData(compLevelCB->currentIndex()).toDouble();
os.setCompressionLevel(level);
}
// Make sure we have the the correct file extension
// so there's no confusion about the codec in use.
auto output_name = m_fileName;
if (!(m_multiExport || output_name.endsWith(m_fileExtension,Qt::CaseInsensitive)))
{
output_name+=m_fileExtension;
}
m_renderManager.reset(new RenderManager(os, m_ft, output_name));
Engine::getSong()->setExportLoop( exportLoopCB->isChecked() );
Engine::getSong()->setRenderBetweenMarkers( renderMarkersCB->isChecked() );
Engine::getSong()->setLoopRenderCount(loopCountSB->value());
connect( m_renderManager.get(), SIGNAL(progressChanged(int)),
progressBar, SLOT(setValue(int)));
connect( m_renderManager.get(), SIGNAL(progressChanged(int)),
this, SLOT(updateTitleBar(int)));
connect( m_renderManager.get(), SIGNAL(finished()),
this, SLOT(accept())) ;
connect( m_renderManager.get(), SIGNAL(finished()),
getGUI()->mainWindow(), SLOT(resetWindowTitle()));
if ( m_multiExport )
{
m_renderManager->renderTracks();
}
else
{
m_renderManager->renderProject();
}
}
void ExportProjectDialog::onFileFormatChanged(int index)
{
// Extract the format tag from the currently selected item,
// and adjust the UI properly.
QVariant format_tag = fileFormatCB->itemData(index);
bool successful_conversion = false;
auto exportFormat = static_cast<ProjectRenderer::ExportFileFormat>(
format_tag.toInt(&successful_conversion)
);
Q_ASSERT(successful_conversion);
bool stereoModeVisible = (exportFormat == ProjectRenderer::ExportFileFormat::MP3);
bool sampleRateControlsVisible = (exportFormat != ProjectRenderer::ExportFileFormat::MP3);
bool bitRateControlsEnabled =
(exportFormat == ProjectRenderer::ExportFileFormat::Ogg ||
exportFormat == ProjectRenderer::ExportFileFormat::MP3);
bool bitDepthControlEnabled =
(exportFormat == ProjectRenderer::ExportFileFormat::Wave ||
exportFormat == ProjectRenderer::ExportFileFormat::Flac);
#ifdef LMMS_HAVE_SF_COMPLEVEL
bool compressionLevelVisible = (exportFormat == ProjectRenderer::ExportFileFormat::Flac);
compressionWidget->setVisible(compressionLevelVisible);
#endif
stereoModeWidget->setVisible(stereoModeVisible);
sampleRateWidget->setVisible(sampleRateControlsVisible);
bitrateWidget->setVisible(bitRateControlsEnabled);
depthWidget->setVisible(bitDepthControlEnabled);
}
void ExportProjectDialog::startBtnClicked()
{
m_ft = ProjectRenderer::ExportFileFormat::Count;
// Get file format from current menu selection.
bool successful_conversion = false;
QVariant tag = fileFormatCB->itemData(fileFormatCB->currentIndex());
m_ft = static_cast<ProjectRenderer::ExportFileFormat>(
tag.toInt(&successful_conversion)
);
if( !successful_conversion )
{
QMessageBox::information( this, tr( "Error" ),
tr( "Error while determining file-encoder device. "
"Please try to choose a different output "
"format." ) );
reject();
return;
}
// Find proper file extension.
for (auto i = std::size_t{0}; i < ProjectRenderer::NumFileFormats; ++i)
{
if (m_ft == ProjectRenderer::fileEncodeDevices[i].m_fileFormat)
{
m_fileExtension = QString( QLatin1String( ProjectRenderer::fileEncodeDevices[i].m_extension ) );
break;
}
}
startButton->setEnabled( false );
progressBar->setEnabled( true );
updateTitleBar( 0 );
startExport();
}
void ExportProjectDialog::updateTitleBar( int _prog )
{
getGUI()->mainWindow()->setWindowTitle(
tr( "Rendering: %1%" ).arg( _prog ) );
setWindowTitle(tr("Rendering: %1%").arg(prog));
}
} // namespace lmms::gui

View File

@@ -1,417 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ExportProjectDialog</class>
<widget class="QDialog" name="ExportProjectDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>379</width>
<height>400</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>379</width>
<height>400</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>379</width>
<height>400</height>
</size>
</property>
<property name="windowTitle">
<string>Export project</string>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QCheckBox" name="exportLoopCB">
<property name="text">
<string>Export as loop (remove extra bar)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="renderMarkersCB">
<property name="text">
<string>Export between loop markers</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="loopRepeatWidget" native="true">
<layout class="QHBoxLayout" name="loopRepeatHL">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelLoopRepeat">
<property name="text">
<string>Render Looped Section:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="loopCountSB">
<property name="suffix">
<string> time(s)</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>2147483647</number> <!-- INT_MAX -->
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QGroupBox" name="outputGroupBox">
<property name="title">
<string>File format settings</string>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>File format:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="fileFormatCB"/>
</item>
<item>
<widget class="QWidget" name="sampleRateWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelSampleRate">
<property name="text">
<string>Sampling rate:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="samplerateCB" />
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="depthWidget" native="true">
<layout class="QVBoxLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelBitDepth">
<property name="text">
<string>Bit depth:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="depthCB">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>16 Bit integer</string>
</property>
</item>
<item>
<property name="text">
<string>24 Bit integer</string>
</property>
</item>
<item>
<property name="text">
<string>32 Bit float</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="stereoModeWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelStereoMode_3">
<property name="text">
<string>Stereo mode:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="stereoModeComboBox">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>Mono</string>
</property>
</item>
<item>
<property name="text">
<string>Stereo</string>
</property>
</item>
<item>
<property name="text">
<string>Joint stereo</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="compressionWidget" native="true">
<layout class="QVBoxLayout" name="_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelCompLevel">
<property name="text">
<string>Compression level:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="compLevelCB">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="bitrateWidget" native="true">
<layout class="QVBoxLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelBitRate">
<property name="text">
<string>Bitrate:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="bitrateCB">
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>64 KBit/s</string>
</property>
</item>
<item>
<property name="text">
<string>128 KBit/s</string>
</property>
</item>
<item>
<property name="text">
<string>160 KBit/s</string>
</property>
</item>
<item>
<property name="text">
<string>192 KBit/s</string>
</property>
</item>
<item>
<property name="text">
<string>256 KBit/s</string>
</property>
</item>
<item>
<property name="text">
<string>320 KBit/s</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="startButton">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>cancelButton</sender>
<signal>clicked()</signal>
<receiver>ExportProjectDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>511</x>
<y>372</y>
</hint>
<hint type="destinationlabel">
<x>202</x>
<y>175</y>
</hint>
</hints>
</connection>
<connection>
<sender>fileFormatCB</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>ExportProjectDialog</receiver>
<slot>onFileFormatChanged(int)</slot>
<hints>
<hint type="sourcelabel">
<x>111</x>
<y>85</y>
</hint>
<hint type="destinationlabel">
<x>518</x>
<y>212</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onFileFormatChanged(int)</slot>
</slots>
</ui>