comparison widgets/PluginParameterDialog.cpp @ 0:fc9323a41f5a

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