annotate widgets/PluginParameterDialog.cpp @ 183:5f86ae638b04

* Omit translucent blue fill for selection rectangles that are superimposed over layers that use colours for meaningful purposes such as the spectrogram (CHARM change request)
author Chris Cannam
date Fri, 24 Nov 2006 16:56:15 +0000
parents 42118892f428
children a5b3c9f580c1
rev   line source
Chris@62 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@62 2
Chris@62 3 /*
Chris@62 4 Sonic Visualiser
Chris@62 5 An audio file viewer and annotation editor.
Chris@62 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@62 8
Chris@62 9 This program is free software; you can redistribute it and/or
Chris@62 10 modify it under the terms of the GNU General Public License as
Chris@62 11 published by the Free Software Foundation; either version 2 of the
Chris@62 12 License, or (at your option) any later version. See the file
Chris@62 13 COPYING included with this distribution for more information.
Chris@62 14 */
Chris@62 15
Chris@62 16 #include "PluginParameterDialog.h"
Chris@62 17
Chris@62 18 #include "PluginParameterBox.h"
Chris@140 19 #include "WindowTypeSelector.h"
Chris@62 20
Chris@106 21 #include "vamp-sdk/Plugin.h"
Chris@147 22 #include "vamp-sdk/PluginHostAdapter.h"
Chris@106 23
Chris@62 24 #include <QGridLayout>
Chris@62 25 #include <QLabel>
Chris@62 26 #include <QGroupBox>
Chris@62 27 #include <QHBoxLayout>
Chris@143 28 #include <QVBoxLayout>
Chris@149 29 #include <QScrollArea>
Chris@62 30 #include <QPushButton>
Chris@69 31 #include <QMessageBox>
Chris@69 32 #include <QComboBox>
Chris@143 33 #include <QSettings>
Chris@62 34
Chris@71 35 PluginParameterDialog::PluginParameterDialog(Vamp::PluginBase *plugin,
Chris@62 36 QWidget *parent) :
Chris@62 37 QDialog(parent),
Chris@62 38 m_plugin(plugin),
Chris@163 39 m_channel(-1),
Chris@145 40 m_stepSize(0),
Chris@145 41 m_blockSize(0),
Chris@145 42 m_windowType(HanningWindow),
Chris@62 43 m_parameterBox(0)
Chris@62 44 {
Chris@122 45 setWindowTitle(tr("Plugin Parameters"));
Chris@122 46
Chris@62 47 QGridLayout *grid = new QGridLayout;
Chris@62 48 setLayout(grid);
Chris@62 49
Chris@62 50 QGroupBox *pluginBox = new QGroupBox;
Chris@62 51 pluginBox->setTitle(tr("Plugin"));
Chris@62 52 grid->addWidget(pluginBox, 0, 0);
Chris@62 53
Chris@62 54 QGridLayout *subgrid = new QGridLayout;
Chris@62 55 pluginBox->setLayout(subgrid);
Chris@62 56
Chris@63 57 subgrid->setSpacing(0);
Chris@63 58 subgrid->setMargin(10);
Chris@63 59
Chris@62 60 QFont font(pluginBox->font());
Chris@62 61 font.setBold(true);
Chris@62 62
Chris@62 63 QLabel *nameLabel = new QLabel(plugin->getDescription().c_str());
Chris@146 64 nameLabel->setWordWrap(true);
Chris@62 65 nameLabel->setFont(font);
Chris@62 66
Chris@62 67 QLabel *makerLabel = new QLabel(plugin->getMaker().c_str());
Chris@146 68 makerLabel->setWordWrap(true);
Chris@62 69
Chris@62 70 QLabel *versionLabel = new QLabel(QString("%1")
Chris@62 71 .arg(plugin->getPluginVersion()));
Chris@146 72 versionLabel->setWordWrap(true);
Chris@62 73
Chris@62 74 QLabel *copyrightLabel = new QLabel(plugin->getCopyright().c_str());
Chris@146 75 copyrightLabel->setWordWrap(true);
Chris@62 76
Chris@63 77 QLabel *typeLabel = new QLabel(plugin->getType().c_str());
Chris@146 78 typeLabel->setWordWrap(true);
Chris@63 79 typeLabel->setFont(font);
Chris@63 80
Chris@163 81 int row = 0;
Chris@163 82
Chris@147 83 QLabel *label = new QLabel(tr("Name:"));
Chris@147 84 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Chris@163 85 subgrid->addWidget(label, row, 0);
Chris@163 86 subgrid->addWidget(nameLabel, row, 1);
Chris@163 87 row++;
Chris@62 88
Chris@147 89 label = new QLabel(tr("Type:"));
Chris@147 90 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Chris@163 91 subgrid->addWidget(label, row, 0);
Chris@163 92 subgrid->addWidget(typeLabel, row, 1);
Chris@163 93 row++;
Chris@164 94
Chris@163 95 m_outputLabel = new QLabel(tr("Output:"));
Chris@163 96 m_outputLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Chris@163 97 subgrid->addWidget(m_outputLabel, row, 0);
Chris@163 98 m_outputValue = new QLabel;
Chris@163 99 subgrid->addWidget(m_outputValue, row, 1);
Chris@163 100 m_outputLabel->hide();
Chris@163 101 m_outputValue->hide();
Chris@163 102 row++;
Chris@62 103
Chris@147 104 label = new QLabel(tr("Maker:"));
Chris@147 105 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Chris@163 106 subgrid->addWidget(label, row, 0);
Chris@163 107 subgrid->addWidget(makerLabel, row, 1);
Chris@163 108 row++;
Chris@63 109
Chris@147 110 label = new QLabel(tr("Copyright: "));
Chris@147 111 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Chris@163 112 subgrid->addWidget(label, row, 0);
Chris@163 113 subgrid->addWidget(copyrightLabel, row, 1);
Chris@163 114 row++;
Chris@106 115
Chris@147 116 label = new QLabel(tr("Version:"));
Chris@147 117 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
Chris@163 118 subgrid->addWidget(label, row, 0);
Chris@163 119 subgrid->addWidget(versionLabel, row, 1);
Chris@163 120 row++;
Chris@62 121
Chris@62 122 subgrid->setColumnStretch(1, 2);
Chris@62 123
Chris@164 124 m_inputModelBox = new QGroupBox;
Chris@164 125 m_inputModelBox->setTitle(tr("Input Source"));
Chris@164 126 grid->addWidget(m_inputModelBox, 1, 0);
Chris@164 127
Chris@164 128 m_inputModels = new QComboBox;
Chris@164 129 QHBoxLayout *inputLayout = new QHBoxLayout;
Chris@164 130 m_inputModelBox->setLayout(inputLayout);
Chris@164 131 inputLayout->addWidget(m_inputModels);
Chris@164 132 m_inputModelBox->hide();
Chris@164 133
Chris@62 134 QGroupBox *paramBox = new QGroupBox;
Chris@62 135 paramBox->setTitle(tr("Plugin Parameters"));
Chris@164 136 grid->addWidget(paramBox, 2, 0);
Chris@164 137 grid->setRowStretch(2, 10);
Chris@62 138
Chris@62 139 QHBoxLayout *paramLayout = new QHBoxLayout;
Chris@63 140 paramLayout->setMargin(0);
Chris@62 141 paramBox->setLayout(paramLayout);
Chris@62 142
Chris@149 143 QScrollArea *scroll = new QScrollArea;
Chris@149 144 scroll->setWidgetResizable(true);
Chris@149 145 scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
Chris@149 146 scroll->setFrameShape(QFrame::NoFrame);
Chris@149 147 paramLayout->addWidget(scroll);
Chris@149 148
Chris@62 149 m_parameterBox = new PluginParameterBox(m_plugin);
Chris@64 150 connect(m_parameterBox, SIGNAL(pluginConfigurationChanged(QString)),
Chris@64 151 this, SIGNAL(pluginConfigurationChanged(QString)));
Chris@149 152 scroll->setWidget(m_parameterBox);
Chris@62 153
Chris@143 154 m_advanced = new QFrame;
Chris@143 155 QVBoxLayout *advancedLayout = new QVBoxLayout;
Chris@143 156 advancedLayout->setMargin(0);
Chris@143 157 m_advanced->setLayout(advancedLayout);
Chris@164 158 grid->addWidget(m_advanced, 3, 0);
Chris@143 159
Chris@143 160 bool haveAdvanced = false;
Chris@143 161
Chris@163 162 m_channelBox = new QGroupBox;
Chris@163 163 m_channelBox->setTitle(tr("Channels"));
Chris@163 164 advancedLayout->addWidget(m_channelBox);
Chris@163 165 m_channelBox->setVisible(false);
Chris@163 166 m_haveChannelBoxData = false;
Chris@163 167
Chris@163 168 m_windowBox = new QGroupBox;
Chris@163 169 m_windowBox->setTitle(tr("Processing"));
Chris@163 170 advancedLayout->addWidget(m_windowBox);
Chris@163 171 m_windowBox->setVisible(false);
Chris@163 172 m_haveWindowBoxData = false;
Chris@163 173
Chris@163 174 QHBoxLayout *hbox = new QHBoxLayout;
Chris@163 175 grid->addLayout(hbox, 4, 0);
Chris@163 176
Chris@163 177 m_advancedVisible = false;
Chris@163 178
Chris@163 179 m_advancedButton = new QPushButton(tr("Advanced >>"));
Chris@163 180 m_advancedButton->setCheckable(true);
Chris@163 181 connect(m_advancedButton, SIGNAL(clicked()), this, SLOT(advancedToggled()));
Chris@163 182
Chris@163 183 QSettings settings;
Chris@163 184 settings.beginGroup("PluginParameterDialog");
Chris@163 185 m_advancedVisible = settings.value("advancedvisible", false).toBool();
Chris@163 186 settings.endGroup();
Chris@163 187
Chris@163 188 m_advanced->setVisible(false);
Chris@163 189
Chris@163 190 hbox->addWidget(m_advancedButton);
Chris@163 191 m_advancedButton->hide();
Chris@163 192
Chris@163 193 QPushButton *ok = new QPushButton(tr("OK"));
Chris@163 194 QPushButton *cancel = new QPushButton(tr("Cancel"));
Chris@163 195 hbox->addStretch(10);
Chris@163 196 hbox->addWidget(ok);
Chris@163 197 hbox->addWidget(cancel);
Chris@163 198 connect(ok, SIGNAL(clicked()), this, SLOT(accept()));
Chris@163 199 connect(cancel, SIGNAL(clicked()), this, SLOT(reject()));
Chris@163 200
Chris@163 201 setAdvancedVisible(m_advancedVisible);
Chris@163 202 }
Chris@163 203
Chris@163 204 PluginParameterDialog::~PluginParameterDialog()
Chris@163 205 {
Chris@163 206 }
Chris@163 207
Chris@163 208
Chris@163 209 void
Chris@163 210 PluginParameterDialog::setOutputLabel(QString text)
Chris@163 211 {
Chris@163 212 if (text == "") {
Chris@163 213 m_outputLabel->hide();
Chris@163 214 m_outputValue->hide();
Chris@163 215 } else {
Chris@163 216 m_outputValue->setText(text);
Chris@163 217 m_outputValue->setWordWrap(true);
Chris@163 218 m_outputLabel->show();
Chris@163 219 m_outputValue->show();
Chris@163 220 }
Chris@163 221 }
Chris@163 222
Chris@163 223 void
Chris@163 224 PluginParameterDialog::setChannelArrangement(int sourceChannels,
Chris@163 225 int targetChannels,
Chris@163 226 int defaultChannel)
Chris@163 227 {
Chris@163 228 m_channel = defaultChannel;
Chris@163 229
Chris@69 230 if (sourceChannels != targetChannels) {
Chris@69 231
Chris@69 232 // At the moment we can only cope with the case where
Chris@69 233 // sourceChannels > targetChannels and targetChannels == 1
Chris@69 234
Chris@69 235 if (sourceChannels < targetChannels) {
Chris@69 236
Chris@69 237 QMessageBox::warning
Chris@163 238 (parentWidget(),
Chris@69 239 tr("Channel mismatch"),
Chris@69 240 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")),
Chris@69 241 QMessageBox::Ok,
Chris@69 242 QMessageBox::NoButton);
Chris@69 243
Chris@69 244 } else {
Chris@69 245
Chris@163 246 if (m_haveChannelBoxData) {
Chris@163 247 std::cerr << "WARNING: PluginParameterDialog::setChannelArrangement: Calling more than once on same dialog is not currently implemented" << std::endl;
Chris@163 248 return;
Chris@163 249 }
Chris@69 250
Chris@69 251 QVBoxLayout *channelLayout = new QVBoxLayout;
Chris@163 252 m_channelBox->setLayout(channelLayout);
Chris@69 253
Chris@69 254 if (targetChannels != 1) {
Chris@69 255
Chris@69 256 channelLayout->addWidget
Chris@69 257 (new QLabel(tr("This plugin accepts no more than %1 input channels,\nbut %2 are available. Only the first %3 will be used.\n")
Chris@69 258 .arg(targetChannels)
Chris@69 259 .arg(sourceChannels)
Chris@69 260 .arg(targetChannels)));
Chris@69 261
Chris@69 262 } else {
Chris@69 263
Chris@69 264 channelLayout->addWidget(new QLabel(tr("This plugin only has a single channel input,\nbut the source has %1 channels.").arg(sourceChannels)));
Chris@69 265
Chris@69 266 QComboBox *channelCombo = new QComboBox;
Chris@76 267 channelCombo->addItem(tr("Use mean of source channels"));
Chris@69 268 for (int i = 0; i < sourceChannels; ++i) {
Chris@69 269 channelCombo->addItem(tr("Use channel %1 only").arg(i + 1));
Chris@69 270 }
Chris@69 271
Chris@69 272 connect(channelCombo, SIGNAL(activated(int)),
Chris@69 273 this, SLOT(channelComboChanged(int)));
Chris@69 274
Chris@69 275 channelLayout->addWidget(channelCombo);
Chris@69 276 }
Chris@163 277
Chris@163 278 m_channelBox->setVisible(true);
Chris@163 279 m_haveChannelBoxData = true;
Chris@163 280 m_advancedButton->show();
Chris@69 281 }
Chris@69 282 }
Chris@69 283
Chris@163 284 setAdvancedVisible(m_advancedVisible);
Chris@163 285 }
Chris@163 286
Chris@163 287 void
Chris@163 288 PluginParameterDialog::setShowProcessingOptions(bool showWindowSize,
Chris@163 289 bool showFrequencyDomainOptions)
Chris@163 290 {
Chris@163 291 if (m_haveWindowBoxData) {
Chris@163 292 std::cerr << "WARNING: PluginParameterDialog::setShowProcessingOptions: Calling more than once on same dialog is not currently implemented" << std::endl;
Chris@163 293 return;
Chris@163 294 }
Chris@163 295
Chris@140 296 if (showWindowSize) {
Chris@140 297
Chris@147 298 Vamp::PluginHostAdapter *fePlugin = dynamic_cast<Vamp::PluginHostAdapter *>(m_plugin);
Chris@140 299 int size = 1024;
Chris@140 300 int increment = 1024;
Chris@140 301 if (fePlugin) {
Chris@140 302 size = fePlugin->getPreferredBlockSize();
Chris@146 303 std::cerr << "Feature extraction plugin \"" << fePlugin->getDescription() << "\" reports preferred block size as " << size << std::endl;
Chris@140 304 if (size == 0) size = 1024;
Chris@140 305 increment = fePlugin->getPreferredStepSize();
Chris@146 306 if (increment == 0) {
Chris@146 307 if (fePlugin->getInputDomain() == Vamp::Plugin::TimeDomain) {
Chris@146 308 increment = size;
Chris@146 309 } else {
Chris@146 310 increment = size/2;
Chris@146 311 }
Chris@146 312 }
Chris@140 313 }
Chris@140 314
Chris@140 315 QGridLayout *windowLayout = new QGridLayout;
Chris@163 316 m_windowBox->setLayout(windowLayout);
Chris@140 317
Chris@140 318 if (showFrequencyDomainOptions) {
Chris@140 319 windowLayout->addWidget(new QLabel(tr("Window size:")), 0, 0);
Chris@140 320 } else {
Chris@140 321 windowLayout->addWidget(new QLabel(tr("Audio frames per block:")), 0, 0);
Chris@140 322 }
Chris@140 323
Chris@143 324 std::cerr << "size: " << size << ", increment: " << increment << std::endl;
Chris@143 325
Chris@140 326 QComboBox *blockSizeCombo = new QComboBox;
Chris@140 327 blockSizeCombo->setEditable(true);
Chris@147 328 bool found = false;
Chris@143 329 for (int i = 0; i < 14; ++i) {
Chris@140 330 int val = pow(2, i + 3);
Chris@140 331 blockSizeCombo->addItem(QString("%1").arg(val));
Chris@147 332 if (val == size) {
Chris@147 333 blockSizeCombo->setCurrentIndex(i);
Chris@147 334 found = true;
Chris@147 335 }
Chris@147 336 }
Chris@147 337 if (!found) {
Chris@147 338 blockSizeCombo->addItem(QString("%1").arg(size));
Chris@147 339 blockSizeCombo->setCurrentIndex(blockSizeCombo->count() - 1);
Chris@140 340 }
Chris@143 341 blockSizeCombo->setValidator(new QIntValidator(1, pow(2, 18), this));
Chris@155 342 connect(blockSizeCombo, SIGNAL(editTextChanged(const QString &)),
Chris@155 343 this, SLOT(blockSizeComboChanged(const QString &)));
Chris@140 344 windowLayout->addWidget(blockSizeCombo, 0, 1);
Chris@140 345
Chris@148 346 windowLayout->addWidget(new QLabel(tr("Window increment:")), 1, 0);
Chris@148 347
Chris@148 348 QComboBox *incrementCombo = new QComboBox;
Chris@148 349 incrementCombo->setEditable(true);
Chris@148 350 found = false;
Chris@148 351 for (int i = 0; i < 14; ++i) {
Chris@148 352 int val = pow(2, i + 3);
Chris@148 353 incrementCombo->addItem(QString("%1").arg(val));
Chris@148 354 if (val == increment) {
Chris@148 355 incrementCombo->setCurrentIndex(i);
Chris@148 356 found = true;
Chris@148 357 }
Chris@148 358 }
Chris@148 359 if (!found) {
Chris@148 360 incrementCombo->addItem(QString("%1").arg(increment));
Chris@148 361 incrementCombo->setCurrentIndex(incrementCombo->count() - 1);
Chris@148 362 }
Chris@148 363 incrementCombo->setValidator(new QIntValidator(1, pow(2, 18), this));
Chris@155 364 connect(incrementCombo, SIGNAL(editTextChanged(const QString &)),
Chris@155 365 this, SLOT(incrementComboChanged(const QString &)));
Chris@148 366 windowLayout->addWidget(incrementCombo, 1, 1);
Chris@148 367
Chris@140 368 if (showFrequencyDomainOptions) {
Chris@140 369
Chris@140 370 windowLayout->addWidget(new QLabel(tr("Window shape:")), 2, 0);
Chris@140 371 WindowTypeSelector *windowTypeSelector = new WindowTypeSelector;
Chris@171 372 connect(windowTypeSelector, SIGNAL(windowTypeChanged(WindowType)),
Chris@171 373 this, SLOT(windowTypeChanged(WindowType)));
Chris@140 374 windowLayout->addWidget(windowTypeSelector, 2, 1);
Chris@140 375 }
Chris@163 376
Chris@163 377 m_windowBox->setVisible(true);
Chris@163 378 m_haveWindowBoxData = true;
Chris@163 379 m_advancedButton->show();
Chris@140 380 }
Chris@140 381
Chris@163 382 setAdvancedVisible(m_advancedVisible);
Chris@62 383 }
Chris@62 384
Chris@69 385 void
Chris@164 386 PluginParameterDialog::setCandidateInputModels(const QStringList &models)
Chris@164 387 {
Chris@164 388 m_inputModels->clear();
Chris@164 389 m_inputModels->insertItems(0, models);
Chris@164 390 connect(m_inputModels, SIGNAL(activated(const QString &)),
Chris@164 391 this, SIGNAL(inputModelChanged(QString)));
Chris@164 392 m_inputModelBox->show();
Chris@164 393 }
Chris@164 394
Chris@164 395 QString
Chris@164 396 PluginParameterDialog::getInputModel() const
Chris@164 397 {
Chris@164 398 return m_inputModels->currentText();
Chris@164 399 }
Chris@164 400
Chris@164 401 void
Chris@145 402 PluginParameterDialog::getProcessingParameters(size_t &blockSize) const
Chris@145 403 {
Chris@145 404 blockSize = m_blockSize;
Chris@145 405 return;
Chris@145 406 }
Chris@145 407
Chris@145 408 void
Chris@145 409 PluginParameterDialog::getProcessingParameters(size_t &stepSize,
Chris@145 410 size_t &blockSize,
Chris@145 411 WindowType &windowType) const
Chris@145 412 {
Chris@145 413 stepSize = m_stepSize;
Chris@145 414 blockSize = m_blockSize;
Chris@145 415 windowType = m_windowType;
Chris@146 416 return;
Chris@145 417 }
Chris@145 418
Chris@145 419 void
Chris@155 420 PluginParameterDialog::blockSizeComboChanged(const QString &text)
Chris@145 421 {
Chris@145 422 m_blockSize = text.toInt();
Chris@146 423 std::cerr << "Block size changed to " << m_blockSize << std::endl;
Chris@145 424 }
Chris@145 425
Chris@145 426 void
Chris@155 427 PluginParameterDialog::incrementComboChanged(const QString &text)
Chris@145 428 {
Chris@145 429 m_stepSize = text.toInt();
Chris@146 430 //!!! rename increment to step size throughout
Chris@147 431 std::cerr << "Increment changed to " << m_stepSize << std::endl;
Chris@145 432 }
Chris@145 433
Chris@145 434 void
Chris@145 435 PluginParameterDialog::windowTypeChanged(WindowType type)
Chris@145 436 {
Chris@145 437 m_windowType = type;
Chris@145 438 }
Chris@145 439
Chris@145 440 void
Chris@143 441 PluginParameterDialog::advancedToggled()
Chris@143 442 {
Chris@163 443 setAdvancedVisible(!m_advancedVisible);
Chris@163 444 }
Chris@143 445
Chris@163 446 void
Chris@163 447 PluginParameterDialog::setAdvancedVisible(bool visible)
Chris@163 448 {
Chris@143 449 m_advanced->setVisible(visible);
Chris@143 450
Chris@163 451 if (visible) {
Chris@163 452 m_advancedButton->setText(tr("Advanced <<"));
Chris@163 453 m_advancedButton->setChecked(true);
Chris@163 454 } else {
Chris@163 455 m_advancedButton->setText(tr("Advanced >>"));
Chris@163 456 m_advancedButton->setChecked(false);
Chris@163 457 }
Chris@143 458
Chris@143 459 QSettings settings;
Chris@143 460 settings.beginGroup("PluginParameterDialog");
Chris@143 461 settings.setValue("advancedvisible", visible);
Chris@143 462 settings.endGroup();
Chris@143 463
Chris@143 464 std::cerr << "resize to " << sizeHint().width() << " x " << sizeHint().height() << std::endl;
Chris@143 465
Chris@149 466 setMinimumHeight(sizeHint().height());
Chris@163 467 adjustSize();
Chris@163 468
Chris@163 469 m_advancedVisible = visible;
Chris@163 470
Chris@163 471 // if (visible) setMaximumHeight(sizeHint().height());
Chris@163 472 // adjustSize();
Chris@143 473 }
Chris@143 474
Chris@143 475 void
Chris@69 476 PluginParameterDialog::channelComboChanged(int index)
Chris@69 477 {
Chris@69 478 m_channel = index - 1;
Chris@69 479 }
Chris@69 480