PluginParameterDialog.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
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 //    QLabel *typeLabel = new QLabel(plugin->getType().c_str());
00087 //    typeLabel->setWordWrap(true);
00088 //    typeLabel->setFont(boldFont);
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 //        label = new QLabel(tr("Description:"));
00107 //        label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00108 //        subgrid->addWidget(label, row, 0);
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 //    label = new QLabel(tr("Type:"));
00125 //    label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00126 //    subgrid->addWidget(label, row, 0);
00127 //    subgrid->addWidget(typeLabel, row, 1);
00128 //    row++;
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         // At the moment we can only cope with the case where
00288         // sourceChannels > targetChannels and targetChannels == 1
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 //    std::cerr << "resize to " << sizeHint().width() << " x " << sizeHint().height() << std::endl;
00576 
00577     setMinimumHeight(sizeHint().height());
00578     adjustSize();
00579 
00580     m_advancedVisible = visible;
00581 
00582 //    if (visible) setMaximumHeight(sizeHint().height());
00583 //    adjustSize();
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 

Generated on Wed Feb 20 15:45:27 2008 for SonicVisualiser by  doxygen 1.5.1