00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "PluginParameterDialog.h"
00017
00018 #include "PluginParameterBox.h"
00019 #include "WindowTypeSelector.h"
00020
00021 #include "base/TextAbbrev.h"
00022
00023 #include "vamp-sdk/Plugin.h"
00024 #include "vamp-sdk/PluginHostAdapter.h"
00025 #include "vamp-sdk/hostext/PluginWrapper.h"
00026
00027 #include <QGridLayout>
00028 #include <QLabel>
00029 #include <QGroupBox>
00030 #include <QHBoxLayout>
00031 #include <QVBoxLayout>
00032 #include <QScrollArea>
00033 #include <QPushButton>
00034 #include <QMessageBox>
00035 #include <QComboBox>
00036 #include <QCheckBox>
00037 #include <QSettings>
00038 #include <QDialogButtonBox>
00039
00040 PluginParameterDialog::PluginParameterDialog(Vamp::PluginBase *plugin,
00041 QWidget *parent) :
00042 QDialog(parent),
00043 m_plugin(plugin),
00044 m_channel(-1),
00045 m_stepSize(0),
00046 m_blockSize(0),
00047 m_windowType(HanningWindow),
00048 m_parameterBox(0),
00049 m_selectionOnly(false)
00050 {
00051 setWindowTitle(tr("Plugin Parameters"));
00052
00053 QGridLayout *grid = new QGridLayout;
00054 setLayout(grid);
00055
00056 QGroupBox *pluginBox = new QGroupBox;
00057 pluginBox->setTitle(plugin->getType().c_str());
00058 grid->addWidget(pluginBox, 0, 0);
00059
00060 QGridLayout *subgrid = new QGridLayout;
00061 pluginBox->setLayout(subgrid);
00062
00063 subgrid->setSpacing(0);
00064 subgrid->setMargin(10);
00065
00066 QFont boldFont(pluginBox->font());
00067 boldFont.setBold(true);
00068
00069 QFont italicFont(pluginBox->font());
00070 italicFont.setItalic(true);
00071
00072 QLabel *nameLabel = new QLabel(plugin->getName().c_str());
00073 nameLabel->setWordWrap(true);
00074 nameLabel->setFont(boldFont);
00075
00076 QLabel *makerLabel = new QLabel(plugin->getMaker().c_str());
00077 makerLabel->setWordWrap(true);
00078
00079 QLabel *versionLabel = new QLabel(QString("%1")
00080 .arg(plugin->getPluginVersion()));
00081 versionLabel->setWordWrap(true);
00082
00083 QLabel *copyrightLabel = new QLabel(plugin->getCopyright().c_str());
00084 copyrightLabel->setWordWrap(true);
00085
00086
00087
00088
00089
00090 QLabel *descriptionLabel = 0;
00091 if (plugin->getDescription() != "") {
00092 descriptionLabel = new QLabel(plugin->getDescription().c_str());
00093 descriptionLabel->setWordWrap(true);
00094 descriptionLabel->setFont(italicFont);
00095 }
00096
00097 int row = 0;
00098
00099 QLabel *label = new QLabel(tr("Name:"));
00100 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00101 subgrid->addWidget(label, row, 0);
00102 subgrid->addWidget(nameLabel, row, 1);
00103 row++;
00104
00105 if (descriptionLabel) {
00106
00107
00108
00109 subgrid->addWidget(descriptionLabel, row, 1);
00110 row++;
00111 }
00112
00113 Vamp::PluginHostAdapter *fePlugin =
00114 dynamic_cast<Vamp::PluginHostAdapter *>(m_plugin);
00115
00116 if (fePlugin) {
00117 label = new QLabel(tr("Version:"));
00118 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00119 subgrid->addWidget(label, row, 0);
00120 subgrid->addWidget(versionLabel, row, 1);
00121 row++;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 label = new QLabel(tr("Maker:"));
00131 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00132 subgrid->addWidget(label, row, 0);
00133 subgrid->addWidget(makerLabel, row, 1);
00134 row++;
00135
00136 label = new QLabel(tr("Copyright: "));
00137 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00138 subgrid->addWidget(label, row, 0);
00139 subgrid->addWidget(copyrightLabel, row, 1);
00140 row++;
00141
00142 m_outputSpacer = new QLabel;
00143 subgrid->addWidget(m_outputSpacer, row, 0);
00144 m_outputSpacer->setFixedHeight(7);
00145 m_outputSpacer->hide();
00146 row++;
00147
00148 m_outputLabel = new QLabel(tr("Output:"));
00149 m_outputLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00150 subgrid->addWidget(m_outputLabel, row, 0);
00151 m_outputValue = new QLabel;
00152 m_outputValue->setFont(boldFont);
00153 subgrid->addWidget(m_outputValue, row, 1);
00154 m_outputLabel->hide();
00155 m_outputValue->hide();
00156 row++;
00157
00158 m_outputDescription = new QLabel;
00159 m_outputDescription->setFont(italicFont);
00160 subgrid->addWidget(m_outputDescription, row, 1);
00161 m_outputDescription->hide();
00162 row++;
00163
00164 subgrid->setColumnStretch(1, 2);
00165
00166 m_inputModelBox = new QGroupBox;
00167 m_inputModelBox->setTitle(tr("Input Material"));
00168 grid->addWidget(m_inputModelBox, 1, 0);
00169
00170 m_inputModels = new QComboBox;
00171 QVBoxLayout *inputLayout = new QVBoxLayout;
00172 m_inputModelBox->setLayout(inputLayout);
00173 inputLayout->addWidget(m_inputModels);
00174 m_inputModels->hide();
00175
00176 m_selectionOnly = new QCheckBox(tr("Restrict to selection extents"));
00177 inputLayout->addWidget(m_selectionOnly);
00178 m_selectionOnly->hide();
00179
00180 m_inputModelBox->hide();
00181
00182 QGroupBox *paramBox = new QGroupBox;
00183 paramBox->setTitle(tr("Plugin Parameters"));
00184 grid->addWidget(paramBox, 2, 0);
00185 grid->setRowStretch(2, 10);
00186
00187 QHBoxLayout *paramLayout = new QHBoxLayout;
00188 paramLayout->setMargin(0);
00189 paramBox->setLayout(paramLayout);
00190
00191 QScrollArea *scroll = new QScrollArea;
00192 scroll->setWidgetResizable(true);
00193 scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00194 scroll->setFrameShape(QFrame::NoFrame);
00195 paramLayout->addWidget(scroll);
00196
00197 m_parameterBox = new PluginParameterBox(m_plugin);
00198 connect(m_parameterBox, SIGNAL(pluginConfigurationChanged(QString)),
00199 this, SIGNAL(pluginConfigurationChanged(QString)));
00200 scroll->setWidget(m_parameterBox);
00201
00202 m_advanced = new QFrame;
00203 QVBoxLayout *advancedLayout = new QVBoxLayout;
00204 advancedLayout->setMargin(0);
00205 m_advanced->setLayout(advancedLayout);
00206 grid->addWidget(m_advanced, 3, 0);
00207
00208 m_channelBox = new QGroupBox;
00209 m_channelBox->setTitle(tr("Channels"));
00210 advancedLayout->addWidget(m_channelBox);
00211 m_channelBox->setVisible(false);
00212 m_haveChannelBoxData = false;
00213
00214 m_windowBox = new QGroupBox;
00215 m_windowBox->setTitle(tr("Processing"));
00216 advancedLayout->addWidget(m_windowBox);
00217 m_windowBox->setVisible(false);
00218 m_haveWindowBoxData = false;
00219
00220 QHBoxLayout *hbox = new QHBoxLayout;
00221 grid->addLayout(hbox, 4, 0);
00222
00223 m_advancedVisible = false;
00224
00225 m_advancedButton = new QPushButton(tr("Advanced >>"));
00226 m_advancedButton->setCheckable(true);
00227 connect(m_advancedButton, SIGNAL(clicked()), this, SLOT(advancedToggled()));
00228
00229 QSettings settings;
00230 settings.beginGroup("PluginParameterDialog");
00231 m_advancedVisible = settings.value("advancedvisible", false).toBool();
00232 settings.endGroup();
00233
00234 m_advanced->setVisible(false);
00235
00236 hbox->addWidget(m_advancedButton);
00237 m_advancedButton->hide();
00238
00239 QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok |
00240 QDialogButtonBox::Cancel);
00241 hbox->addWidget(bb);
00242 connect(bb, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
00243 connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
00244
00245 setAdvancedVisible(m_advancedVisible);
00246 }
00247
00248 PluginParameterDialog::~PluginParameterDialog()
00249 {
00250 }
00251
00252
00253 void
00254 PluginParameterDialog::setOutputLabel(QString text,
00255 QString description)
00256 {
00257 if (text == "") {
00258 m_outputSpacer->hide();
00259 m_outputLabel->hide();
00260 m_outputValue->hide();
00261 m_outputDescription->hide();
00262 } else {
00263 m_outputSpacer->show();
00264 m_outputValue->setText(text);
00265 m_outputValue->setWordWrap(true);
00266 m_outputDescription->setText(description);
00267 m_outputDescription->setWordWrap(true);
00268 m_outputLabel->show();
00269 m_outputValue->show();
00270 if (description != "") {
00271 m_outputDescription->show();
00272 } else {
00273 m_outputDescription->hide();
00274 }
00275 }
00276 }
00277
00278 void
00279 PluginParameterDialog::setChannelArrangement(int sourceChannels,
00280 int targetChannels,
00281 int defaultChannel)
00282 {
00283 m_channel = defaultChannel;
00284
00285 if (sourceChannels != targetChannels) {
00286
00287
00288
00289
00290 if (sourceChannels < targetChannels) {
00291
00292 QMessageBox::warning
00293 (parentWidget(),
00294 tr("Channel mismatch"),
00295 tr("This plugin requires at least %1 input channels, but only %2 %3 available. The plugin probably will not work correctly.").arg(targetChannels).arg(sourceChannels).arg(sourceChannels != 1 ? tr("are") : tr("is")),
00296 QMessageBox::Ok,
00297 QMessageBox::NoButton);
00298
00299 } else {
00300
00301 if (m_haveChannelBoxData) {
00302 std::cerr << "WARNING: PluginParameterDialog::setChannelArrangement: Calling more than once on same dialog is not currently implemented" << std::endl;
00303 return;
00304 }
00305
00306 QVBoxLayout *channelLayout = new QVBoxLayout;
00307 m_channelBox->setLayout(channelLayout);
00308
00309 if (targetChannels != 1) {
00310
00311 channelLayout->addWidget
00312 (new QLabel(tr("This plugin accepts no more than %1 input channels,\nbut %2 are available. Only the first %3 will be used.\n")
00313 .arg(targetChannels)
00314 .arg(sourceChannels)
00315 .arg(targetChannels)));
00316
00317 } else {
00318
00319 channelLayout->addWidget(new QLabel(tr("This plugin only has a single channel input,\nbut the source has %1 channels.").arg(sourceChannels)));
00320
00321 QComboBox *channelCombo = new QComboBox;
00322 channelCombo->addItem(tr("Use mean of source channels"));
00323 for (int i = 0; i < sourceChannels; ++i) {
00324 channelCombo->addItem(tr("Use channel %1 only").arg(i + 1));
00325 }
00326
00327 connect(channelCombo, SIGNAL(activated(int)),
00328 this, SLOT(channelComboChanged(int)));
00329
00330 channelLayout->addWidget(channelCombo);
00331 }
00332
00333 m_channelBox->setVisible(true);
00334 m_haveChannelBoxData = true;
00335 m_advancedButton->show();
00336 }
00337 }
00338
00339 setAdvancedVisible(m_advancedVisible);
00340 }
00341
00342 void
00343 PluginParameterDialog::setShowProcessingOptions(bool showWindowSize,
00344 bool showFrequencyDomainOptions)
00345 {
00346 if (m_haveWindowBoxData) {
00347 std::cerr << "WARNING: PluginParameterDialog::setShowProcessingOptions: Calling more than once on same dialog is not currently implemented" << std::endl;
00348 return;
00349 }
00350
00351 if (showWindowSize) {
00352
00353 Vamp::Plugin *fePlugin = dynamic_cast<Vamp::Plugin *>(m_plugin);
00354 if (!fePlugin) fePlugin = dynamic_cast<Vamp::PluginHostAdapter *>(m_plugin);
00355 if (!fePlugin) fePlugin = dynamic_cast<Vamp::HostExt::PluginWrapper *>(m_plugin);
00356 int size = 1024;
00357 int increment = 1024;
00358 if (fePlugin) {
00359 size = fePlugin->getPreferredBlockSize();
00360 std::cerr << "Feature extraction plugin \"" << fePlugin->getName() << "\" reports preferred block size as " << size << std::endl;
00361 if (size == 0) size = 1024;
00362 increment = fePlugin->getPreferredStepSize();
00363 if (increment == 0) {
00364 if (fePlugin->getInputDomain() == Vamp::Plugin::TimeDomain) {
00365 increment = size;
00366 } else {
00367 increment = size/2;
00368 }
00369 }
00370 }
00371
00372 QGridLayout *windowLayout = new QGridLayout;
00373 m_windowBox->setLayout(windowLayout);
00374
00375 if (showFrequencyDomainOptions) {
00376 windowLayout->addWidget(new QLabel(tr("Window size:")), 0, 0);
00377 } else {
00378 windowLayout->addWidget(new QLabel(tr("Audio frames per block:")), 0, 0);
00379 }
00380
00381 std::cerr << "size: " << size << ", increment: " << increment << std::endl;
00382
00383 QComboBox *blockSizeCombo = new QComboBox;
00384 blockSizeCombo->setEditable(true);
00385 bool found = false;
00386 for (int i = 0; i < 14; ++i) {
00387 int val = 1 << (i + 3);
00388 blockSizeCombo->addItem(QString("%1").arg(val));
00389 if (val == size) {
00390 blockSizeCombo->setCurrentIndex(i);
00391 found = true;
00392 }
00393 }
00394 if (!found) {
00395 blockSizeCombo->addItem(QString("%1").arg(size));
00396 blockSizeCombo->setCurrentIndex(blockSizeCombo->count() - 1);
00397 }
00398 blockSizeCombo->setValidator(new QIntValidator(1, int(pow(2, 18)), this));
00399 connect(blockSizeCombo, SIGNAL(editTextChanged(const QString &)),
00400 this, SLOT(blockSizeComboChanged(const QString &)));
00401 windowLayout->addWidget(blockSizeCombo, 0, 1);
00402
00403 windowLayout->addWidget(new QLabel(tr("Window increment:")), 1, 0);
00404
00405 QComboBox *incrementCombo = new QComboBox;
00406 incrementCombo->setEditable(true);
00407 found = false;
00408 for (int i = 0; i < 14; ++i) {
00409 int val = 1 << (i + 3);
00410 incrementCombo->addItem(QString("%1").arg(val));
00411 if (val == increment) {
00412 incrementCombo->setCurrentIndex(i);
00413 found = true;
00414 }
00415 }
00416 if (!found) {
00417 incrementCombo->addItem(QString("%1").arg(increment));
00418 incrementCombo->setCurrentIndex(incrementCombo->count() - 1);
00419 }
00420 incrementCombo->setValidator(new QIntValidator(1, int(pow(2, 18)), this));
00421 connect(incrementCombo, SIGNAL(editTextChanged(const QString &)),
00422 this, SLOT(incrementComboChanged(const QString &)));
00423 windowLayout->addWidget(incrementCombo, 1, 1);
00424
00425 if (showFrequencyDomainOptions) {
00426
00427 windowLayout->addWidget(new QLabel(tr("Window shape:")), 2, 0);
00428 WindowTypeSelector *windowTypeSelector = new WindowTypeSelector;
00429 connect(windowTypeSelector, SIGNAL(windowTypeChanged(WindowType)),
00430 this, SLOT(windowTypeChanged(WindowType)));
00431 windowLayout->addWidget(windowTypeSelector, 2, 1);
00432 }
00433
00434 m_windowBox->setVisible(true);
00435 m_haveWindowBoxData = true;
00436 m_advancedButton->show();
00437 }
00438
00439 setAdvancedVisible(m_advancedVisible);
00440 }
00441
00442 void
00443 PluginParameterDialog::setCandidateInputModels(const QStringList &models,
00444 QString defaultModel)
00445 {
00446 m_inputModels->clear();
00447
00448 QSettings settings;
00449 settings.beginGroup("PluginParameterDialog");
00450 QString lastModel = settings.value("lastinputmodel").toString();
00451 settings.endGroup();
00452
00453 if (defaultModel == "") defaultModel = lastModel;
00454
00455 m_inputModels->show();
00456
00457 m_inputModelList = models;
00458 m_inputModels->addItems(TextAbbrev::abbreviate(models, 80));
00459 m_inputModels->setCurrentIndex(0);
00460
00461 if (defaultModel != "") {
00462 for (int i = 0; i < models.size(); ++i) {
00463 if (defaultModel == models[i]) {
00464 m_inputModels->setCurrentIndex(i);
00465 m_currentInputModel = models[i];
00466 break;
00467 }
00468 }
00469 }
00470
00471 connect(m_inputModels, SIGNAL(activated(int)),
00472 this, SLOT(inputModelComboChanged(int)));
00473 m_inputModelBox->show();
00474 }
00475
00476 void
00477 PluginParameterDialog::setShowSelectionOnlyOption(bool show)
00478 {
00479 if (!show) {
00480 m_selectionOnly->hide();
00481 if (!m_inputModels->isVisible()) m_inputModelBox->hide();
00482 return;
00483 }
00484
00485 QSettings settings;
00486 settings.beginGroup("PluginParameterDialog");
00487 bool lastSelectionOnly = settings.value("lastselectiononly", false).toBool();
00488 settings.endGroup();
00489
00490 m_selectionOnly->setChecked(lastSelectionOnly);
00491 m_currentSelectionOnly = lastSelectionOnly;
00492
00493 connect(m_selectionOnly, SIGNAL(stateChanged(int)),
00494 this, SLOT(selectionOnlyChanged(int)));
00495
00496 m_selectionOnly->show();
00497 m_inputModelBox->show();
00498 }
00499
00500 QString
00501 PluginParameterDialog::getInputModel() const
00502 {
00503 return m_currentInputModel;
00504 }
00505
00506 bool
00507 PluginParameterDialog::getSelectionOnly() const
00508 {
00509 return m_currentSelectionOnly;
00510 }
00511
00512 void
00513 PluginParameterDialog::getProcessingParameters(size_t &blockSize) const
00514 {
00515 blockSize = m_blockSize;
00516 return;
00517 }
00518
00519 void
00520 PluginParameterDialog::getProcessingParameters(size_t &stepSize,
00521 size_t &blockSize,
00522 WindowType &windowType) const
00523 {
00524 stepSize = m_stepSize;
00525 blockSize = m_blockSize;
00526 windowType = m_windowType;
00527 return;
00528 }
00529
00530 void
00531 PluginParameterDialog::blockSizeComboChanged(const QString &text)
00532 {
00533 m_blockSize = text.toInt();
00534 std::cerr << "Block size changed to " << m_blockSize << std::endl;
00535 }
00536
00537 void
00538 PluginParameterDialog::incrementComboChanged(const QString &text)
00539 {
00540 m_stepSize = text.toInt();
00542 std::cerr << "Increment changed to " << m_stepSize << std::endl;
00543 }
00544
00545 void
00546 PluginParameterDialog::windowTypeChanged(WindowType type)
00547 {
00548 m_windowType = type;
00549 }
00550
00551 void
00552 PluginParameterDialog::advancedToggled()
00553 {
00554 setAdvancedVisible(!m_advancedVisible);
00555 }
00556
00557 void
00558 PluginParameterDialog::setAdvancedVisible(bool visible)
00559 {
00560 m_advanced->setVisible(visible);
00561
00562 if (visible) {
00563 m_advancedButton->setText(tr("Advanced <<"));
00564 m_advancedButton->setChecked(true);
00565 } else {
00566 m_advancedButton->setText(tr("Advanced >>"));
00567 m_advancedButton->setChecked(false);
00568 }
00569
00570 QSettings settings;
00571 settings.beginGroup("PluginParameterDialog");
00572 settings.setValue("advancedvisible", visible);
00573 settings.endGroup();
00574
00575
00576
00577 setMinimumHeight(sizeHint().height());
00578 adjustSize();
00579
00580 m_advancedVisible = visible;
00581
00582
00583
00584 }
00585
00586 void
00587 PluginParameterDialog::channelComboChanged(int index)
00588 {
00589 m_channel = index - 1;
00590 }
00591
00592 void
00593 PluginParameterDialog::inputModelComboChanged(int index)
00594 {
00595 if (index >= m_inputModelList.size()) return;
00596 m_currentInputModel = m_inputModelList[index];
00597 emit inputModelChanged(m_currentInputModel);
00598 }
00599
00600 void
00601 PluginParameterDialog::selectionOnlyChanged(int state)
00602 {
00603 if (state == Qt::Checked) {
00604 m_currentSelectionOnly = true;
00605 } else {
00606 m_currentSelectionOnly = false;
00607 }
00608 }
00609
00610 void
00611 PluginParameterDialog::dialogAccepted()
00612 {
00613 QSettings settings;
00614 settings.beginGroup("PluginParameterDialog");
00615
00616 if (m_inputModels->isVisible()) {
00617 settings.setValue("lastinputmodel", getInputModel());
00618 }
00619
00620 if (m_selectionOnly->isVisible()) {
00621 settings.setValue("lastselectiononly", getSelectionOnly());
00622 }
00623
00624 settings.endGroup();
00625
00626 accept();
00627 }
00628