annotate widgets/PropertyBox.cpp @ 640:c6d705bf1672

Merge from branch "qt5". This revision actually builds with Qt4 (late releases) or Qt5, though it will warn on configure with Qt4.
author Chris Cannam
date Tue, 14 May 2013 12:36:43 +0100
parents 4806715f7a19
children 3437e0fad7ae eaf4446a1bef
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "PropertyBox.h"
Chris@63 17 #include "PluginParameterDialog.h"
Chris@0 18
Chris@0 19 #include "base/PropertyContainer.h"
Chris@33 20 #include "base/PlayParameters.h"
Chris@377 21 #include "base/PlayParameterRepository.h"
Chris@128 22 #include "layer/Layer.h"
Chris@376 23 #include "layer/ColourDatabase.h"
Chris@100 24 #include "base/UnitDatabase.h"
Chris@167 25 #include "base/RangeMapper.h"
Chris@0 26
Chris@63 27 #include "plugin/RealTimePluginFactory.h"
Chris@63 28 #include "plugin/RealTimePluginInstance.h"
Chris@71 29 #include "plugin/PluginXml.h"
Chris@63 30
Chris@0 31 #include "AudioDial.h"
Chris@33 32 #include "LEDButton.h"
Chris@335 33 #include "IconLoader.h"
Chris@0 34
Chris@189 35 #include "NotifyingCheckBox.h"
Chris@189 36 #include "NotifyingComboBox.h"
Chris@335 37 #include "NotifyingPushButton.h"
Chris@285 38 #include "ColourNameDialog.h"
Chris@189 39
Chris@0 40 #include <QGridLayout>
Chris@0 41 #include <QHBoxLayout>
Chris@33 42 #include <QVBoxLayout>
Chris@63 43 #include <QPushButton>
Chris@0 44 #include <QLabel>
Chris@33 45 #include <QFrame>
Chris@218 46 #include <QApplication>
Chris@285 47 #include <QColorDialog>
Chris@285 48 #include <QInputDialog>
Chris@0 49
Chris@0 50 #include <cassert>
Chris@0 51 #include <iostream>
Martin@46 52 #include <cmath>
Chris@0 53
Chris@456 54 //#define DEBUG_PROPERTY_BOX 1
Chris@0 55
Chris@0 56 PropertyBox::PropertyBox(PropertyContainer *container) :
Chris@185 57 m_container(container),
Chris@189 58 m_showButton(0),
Chris@189 59 m_playButton(0)
Chris@0 60 {
Chris@0 61 #ifdef DEBUG_PROPERTY_BOX
Chris@0 62 std::cerr << "PropertyBox[" << this << "(\"" <<
Chris@584 63 container->getPropertyContainerName() << "\" at " << container << ")]::PropertyBox" << std::endl;
Chris@0 64 #endif
Chris@0 65
Chris@34 66 m_mainBox = new QVBoxLayout;
Chris@34 67 setLayout(m_mainBox);
Chris@33 68
Chris@107 69 // m_nameWidget = new QLabel;
Chris@107 70 // m_mainBox->addWidget(m_nameWidget);
Chris@107 71 // m_nameWidget->setText(container->objectName());
Chris@107 72
Chris@34 73 m_mainWidget = new QWidget;
Chris@34 74 m_mainBox->addWidget(m_mainWidget);
Chris@107 75 m_mainBox->insertStretch(2, 10);
Chris@33 76
Chris@34 77 m_viewPlayFrame = 0;
Chris@34 78 populateViewPlayFrame();
Chris@33 79
Chris@0 80 m_layout = new QGridLayout;
Chris@34 81 m_layout->setMargin(0);
Chris@33 82 m_mainWidget->setLayout(m_layout);
Chris@0 83
Chris@34 84 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@0 85
Chris@0 86 blockSignals(true);
Chris@0 87
Chris@0 88 size_t i;
Chris@0 89
Chris@0 90 for (i = 0; i < properties.size(); ++i) {
Chris@0 91 updatePropertyEditor(properties[i]);
Chris@0 92 }
Chris@0 93
Chris@0 94 blockSignals(false);
Chris@0 95
Chris@0 96 m_layout->setRowStretch(m_layout->rowCount(), 10);
Chris@0 97
Chris@100 98 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()),
Chris@100 99 this, SLOT(unitDatabaseChanged()));
Chris@100 100
Chris@285 101 connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()),
Chris@285 102 this, SLOT(colourDatabaseChanged()));
Chris@285 103
Chris@0 104 #ifdef DEBUG_PROPERTY_BOX
Chris@0 105 std::cerr << "PropertyBox[" << this << "]::PropertyBox returning" << std::endl;
Chris@0 106 #endif
Chris@0 107 }
Chris@0 108
Chris@0 109 PropertyBox::~PropertyBox()
Chris@0 110 {
Chris@0 111 #ifdef DEBUG_PROPERTY_BOX
Chris@33 112 std::cerr << "PropertyBox[" << this << "]::~PropertyBox" << std::endl;
Chris@0 113 #endif
Chris@0 114 }
Chris@0 115
Chris@0 116 void
Chris@34 117 PropertyBox::populateViewPlayFrame()
Chris@33 118 {
Chris@36 119 #ifdef DEBUG_PROPERTY_BOX
Chris@34 120 std::cerr << "PropertyBox(" << m_container << ")::populateViewPlayFrame" << std::endl;
Chris@36 121 #endif
Chris@34 122
Chris@34 123 if (m_viewPlayFrame) {
Chris@34 124 delete m_viewPlayFrame;
Chris@34 125 m_viewPlayFrame = 0;
Chris@34 126 }
Chris@34 127
Chris@34 128 if (!m_container) return;
Chris@34 129
Chris@34 130 Layer *layer = dynamic_cast<Layer *>(m_container);
Chris@34 131 if (layer) {
Chris@193 132 disconnect(layer, SIGNAL(modelReplaced()),
Chris@193 133 this, SLOT(populateViewPlayFrame()));
Chris@34 134 connect(layer, SIGNAL(modelReplaced()),
Chris@34 135 this, SLOT(populateViewPlayFrame()));
Chris@34 136 }
Chris@34 137
Chris@34 138 PlayParameters *params = m_container->getPlayParameters();
Chris@33 139 if (!params && !layer) return;
Chris@33 140
Chris@34 141 m_viewPlayFrame = new QFrame;
Chris@34 142 m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
Chris@34 143 m_mainBox->addWidget(m_viewPlayFrame);
Chris@34 144
Chris@34 145 QHBoxLayout *layout = new QHBoxLayout;
Chris@34 146 m_viewPlayFrame->setLayout(layout);
Chris@34 147
Chris@34 148 layout->setMargin(layout->margin() / 2);
Chris@34 149
Chris@36 150 #ifdef DEBUG_PROPERTY_BOX
Chris@587 151 SVDEBUG << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName() << ") params " << params << endl;
Chris@36 152 #endif
Chris@36 153
Chris@33 154 if (layer) {
Chris@34 155 QLabel *showLabel = new QLabel(tr("Show"));
Chris@34 156 layout->addWidget(showLabel);
Chris@34 157 layout->setAlignment(showLabel, Qt::AlignVCenter);
Chris@34 158
Chris@185 159 m_showButton = new LEDButton(Qt::blue);
Chris@185 160 layout->addWidget(m_showButton);
Chris@185 161 connect(m_showButton, SIGNAL(stateChanged(bool)),
Chris@47 162 this, SIGNAL(showLayer(bool)));
Chris@189 163 connect(m_showButton, SIGNAL(mouseEntered()),
Chris@189 164 this, SLOT(mouseEnteredWidget()));
Chris@189 165 connect(m_showButton, SIGNAL(mouseLeft()),
Chris@189 166 this, SLOT(mouseLeftWidget()));
Chris@185 167 layout->setAlignment(m_showButton, Qt::AlignVCenter);
Chris@33 168 }
Chris@33 169
Chris@33 170 if (params) {
Chris@34 171
Chris@34 172 QLabel *playLabel = new QLabel(tr("Play"));
Chris@34 173 layout->addWidget(playLabel);
Chris@34 174 layout->setAlignment(playLabel, Qt::AlignVCenter);
Chris@34 175
Chris@189 176 m_playButton = new LEDButton(Qt::darkGreen);
Chris@189 177 m_playButton->setState(!params->isPlayMuted());
Chris@189 178 layout->addWidget(m_playButton);
Chris@189 179 connect(m_playButton, SIGNAL(stateChanged(bool)),
Chris@377 180 this, SLOT(playAudibleButtonChanged(bool)));
Chris@189 181 connect(m_playButton, SIGNAL(mouseEntered()),
Chris@189 182 this, SLOT(mouseEnteredWidget()));
Chris@189 183 connect(m_playButton, SIGNAL(mouseLeft()),
Chris@189 184 this, SLOT(mouseLeftWidget()));
Chris@34 185 connect(params, SIGNAL(playAudibleChanged(bool)),
Chris@377 186 this, SLOT(playAudibleChanged(bool)));
Chris@189 187 layout->setAlignment(m_playButton, Qt::AlignVCenter);
Chris@34 188
Chris@34 189 layout->insertStretch(-1, 10);
Chris@34 190
Chris@63 191 if (params->getPlayPluginId() != "") {
Chris@64 192 QPushButton *pluginButton = new QPushButton(QIcon(":icons/faders.png"), "");
Chris@64 193 pluginButton->setFixedWidth(24);
Chris@64 194 pluginButton->setFixedHeight(24);
Chris@63 195 layout->addWidget(pluginButton);
Chris@63 196 connect(pluginButton, SIGNAL(clicked()),
Chris@63 197 this, SLOT(editPlugin()));
Chris@63 198 }
Chris@63 199
Chris@34 200 AudioDial *gainDial = new AudioDial;
Chris@34 201 layout->addWidget(gainDial);
Chris@34 202 gainDial->setMeterColor(Qt::darkRed);
Chris@34 203 gainDial->setMinimum(-50);
Chris@34 204 gainDial->setMaximum(50);
Chris@34 205 gainDial->setPageStep(1);
Chris@34 206 gainDial->setFixedWidth(24);
Chris@34 207 gainDial->setFixedHeight(24);
Chris@34 208 gainDial->setNotchesVisible(false);
Chris@34 209 gainDial->setDefaultValue(0);
Chris@168 210 gainDial->setObjectName(tr("Playback Gain"));
Chris@167 211 gainDial->setRangeMapper(new LinearRangeMapper
Chris@167 212 (-50, 50, -25, 25, tr("dB")));
Chris@168 213 gainDial->setShowToolTip(true);
Chris@34 214 connect(gainDial, SIGNAL(valueChanged(int)),
Chris@34 215 this, SLOT(playGainDialChanged(int)));
Chris@34 216 connect(params, SIGNAL(playGainChanged(float)),
Chris@34 217 this, SLOT(playGainChanged(float)));
Chris@34 218 connect(this, SIGNAL(changePlayGainDial(int)),
Chris@34 219 gainDial, SLOT(setValue(int)));
Chris@189 220 connect(gainDial, SIGNAL(mouseEntered()),
Chris@189 221 this, SLOT(mouseEnteredWidget()));
Chris@189 222 connect(gainDial, SIGNAL(mouseLeft()),
Chris@189 223 this, SLOT(mouseLeftWidget()));
Chris@377 224 playGainChanged(params->getPlayGain());
Chris@34 225 layout->setAlignment(gainDial, Qt::AlignVCenter);
Chris@34 226
Chris@34 227 AudioDial *panDial = new AudioDial;
Chris@34 228 layout->addWidget(panDial);
Chris@34 229 panDial->setMeterColor(Qt::darkGreen);
Chris@34 230 panDial->setMinimum(-50);
Chris@34 231 panDial->setMaximum(50);
Chris@34 232 panDial->setPageStep(1);
Chris@34 233 panDial->setFixedWidth(24);
Chris@34 234 panDial->setFixedHeight(24);
Chris@34 235 panDial->setNotchesVisible(false);
Chris@57 236 panDial->setToolTip(tr("Playback Pan / Balance"));
Chris@34 237 panDial->setDefaultValue(0);
Chris@168 238 panDial->setObjectName(tr("Playback Pan / Balance"));
Chris@168 239 panDial->setShowToolTip(true);
Chris@34 240 connect(panDial, SIGNAL(valueChanged(int)),
Chris@34 241 this, SLOT(playPanDialChanged(int)));
Chris@34 242 connect(params, SIGNAL(playPanChanged(float)),
Chris@34 243 this, SLOT(playPanChanged(float)));
Chris@34 244 connect(this, SIGNAL(changePlayPanDial(int)),
Chris@34 245 panDial, SLOT(setValue(int)));
Chris@189 246 connect(panDial, SIGNAL(mouseEntered()),
Chris@189 247 this, SLOT(mouseEnteredWidget()));
Chris@189 248 connect(panDial, SIGNAL(mouseLeft()),
Chris@189 249 this, SLOT(mouseLeftWidget()));
Chris@377 250 playPanChanged(params->getPlayPan());
Chris@34 251 layout->setAlignment(panDial, Qt::AlignVCenter);
Chris@34 252
Chris@34 253 } else {
Chris@34 254
Chris@34 255 layout->insertStretch(-1, 10);
Chris@33 256 }
Chris@33 257 }
Chris@33 258
Chris@33 259 void
Chris@197 260 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name,
Chris@197 261 bool rangeChanged)
Chris@0 262 {
Chris@0 263 PropertyContainer::PropertyType type = m_container->getPropertyType(name);
Chris@0 264 int row = m_layout->rowCount();
Chris@0 265
Chris@216 266 int min = 0, max = 0, value = 0, deflt = 0;
Chris@216 267 value = m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
Chris@0 268
Chris@0 269 bool have = (m_propertyControllers.find(name) !=
Chris@0 270 m_propertyControllers.end());
Chris@0 271
Chris@0 272 QString groupName = m_container->getPropertyGroupName(name);
Chris@87 273 QString propertyLabel = m_container->getPropertyLabel(name);
Chris@335 274 QString iconName = m_container->getPropertyIconName(name);
Chris@0 275
Chris@0 276 #ifdef DEBUG_PROPERTY_BOX
Chris@0 277 std::cerr << "PropertyBox[" << this
Chris@0 278 << "(\"" << m_container->getPropertyContainerName().toStdString()
Chris@0 279 << "\")]";
Chris@584 280 std::cerr << "::updatePropertyEditor(\"" << name << "\"):";
Chris@0 281 std::cerr << " value " << value << ", have " << have << ", group \""
Chris@584 282 << groupName << "\"" << std::endl;
Chris@0 283 #endif
Chris@0 284
Chris@0 285 bool inGroup = (groupName != QString());
Chris@0 286
Chris@0 287 if (!have) {
Chris@0 288 if (inGroup) {
Chris@0 289 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
Chris@0 290 #ifdef DEBUG_PROPERTY_BOX
Chris@584 291 std::cerr << "PropertyBox: adding label \"" << groupName << "\" and frame for group for \"" << name << "\"" << std::endl;
Chris@0 292 #endif
Chris@33 293 m_layout->addWidget(new QLabel(groupName, m_mainWidget), row, 0);
Chris@33 294 QFrame *frame = new QFrame(m_mainWidget);
Chris@0 295 m_layout->addWidget(frame, row, 1, 1, 2);
Chris@493 296 m_groupLayouts[groupName] = new QGridLayout;
Chris@0 297 m_groupLayouts[groupName]->setMargin(0);
Chris@0 298 frame->setLayout(m_groupLayouts[groupName]);
Chris@0 299 }
Chris@0 300 } else {
Chris@0 301 #ifdef DEBUG_PROPERTY_BOX
Chris@584 302 std::cerr << "PropertyBox: adding label \"" << propertyLabel << "\"" << std::endl;
Chris@0 303 #endif
Chris@87 304 m_layout->addWidget(new QLabel(propertyLabel, m_mainWidget), row, 0);
Chris@0 305 }
Chris@0 306 }
Chris@0 307
Chris@0 308 switch (type) {
Chris@0 309
Chris@0 310 case PropertyContainer::ToggleProperty:
Chris@0 311 {
Chris@335 312 QAbstractButton *button = 0;
Chris@0 313
Chris@0 314 if (have) {
Chris@335 315 button = dynamic_cast<QAbstractButton *>(m_propertyControllers[name]);
Chris@335 316 assert(button);
Chris@0 317 } else {
Chris@0 318 #ifdef DEBUG_PROPERTY_BOX
Chris@0 319 std::cerr << "PropertyBox: creating new checkbox" << std::endl;
Chris@0 320 #endif
Chris@335 321 if (iconName != "") {
Chris@335 322 button = new NotifyingPushButton();
Chris@335 323 button->setCheckable(true);
Chris@335 324 QIcon icon(IconLoader().load(iconName));
Chris@335 325 button->setIcon(icon);
Chris@335 326 button->setObjectName(name);
Chris@335 327 button->setFixedSize(QSize(18, 18));
Chris@335 328 } else {
Chris@335 329 button = new NotifyingCheckBox();
Chris@335 330 button->setObjectName(name);
Chris@335 331 }
Chris@335 332 connect(button, SIGNAL(toggled(bool)),
Chris@335 333 this, SLOT(propertyControllerChanged(bool)));
Chris@335 334 connect(button, SIGNAL(mouseEntered()),
Chris@189 335 this, SLOT(mouseEnteredWidget()));
Chris@335 336 connect(button, SIGNAL(mouseLeft()),
Chris@189 337 this, SLOT(mouseLeftWidget()));
Chris@0 338 if (inGroup) {
Chris@335 339 button->setToolTip(propertyLabel);
Chris@493 340 m_groupLayouts[groupName]->addWidget
Chris@493 341 (button, 0, m_groupLayouts[groupName]->columnCount());
Chris@0 342 } else {
Chris@335 343 m_layout->addWidget(button, row, 1, 1, 2);
Chris@0 344 }
Chris@335 345 m_propertyControllers[name] = button;
Chris@0 346 }
Chris@0 347
Chris@335 348 if (button->isChecked() != (value > 0)) {
Chris@335 349 button->blockSignals(true);
Chris@335 350 button->setChecked(value > 0);
Chris@335 351 button->blockSignals(false);
Chris@55 352 }
Chris@0 353 break;
Chris@0 354 }
Chris@0 355
Chris@0 356 case PropertyContainer::RangeProperty:
Chris@0 357 {
Chris@0 358 AudioDial *dial;
Chris@0 359
Chris@0 360 if (have) {
Chris@0 361 dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]);
Chris@0 362 assert(dial);
Chris@197 363 if (rangeChanged) {
Chris@197 364 dial->blockSignals(true);
Chris@197 365 dial->setMinimum(min);
Chris@197 366 dial->setMaximum(max);
Chris@197 367 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name));
Chris@197 368 dial->blockSignals(false);
Chris@197 369 }
Chris@197 370
Chris@0 371 } else {
Chris@0 372 #ifdef DEBUG_PROPERTY_BOX
Chris@0 373 std::cerr << "PropertyBox: creating new dial" << std::endl;
Chris@0 374 #endif
Chris@0 375 dial = new AudioDial();
Chris@0 376 dial->setObjectName(name);
Chris@0 377 dial->setMinimum(min);
Chris@0 378 dial->setMaximum(max);
Chris@0 379 dial->setPageStep(1);
Chris@34 380 dial->setNotchesVisible((max - min) <= 12);
Chris@216 381 dial->setDefaultValue(deflt);
Chris@167 382 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name));
Chris@168 383 dial->setShowToolTip(true);
Chris@0 384 connect(dial, SIGNAL(valueChanged(int)),
Chris@0 385 this, SLOT(propertyControllerChanged(int)));
Chris@189 386 connect(dial, SIGNAL(mouseEntered()),
Chris@189 387 this, SLOT(mouseEnteredWidget()));
Chris@189 388 connect(dial, SIGNAL(mouseLeft()),
Chris@189 389 this, SLOT(mouseLeftWidget()));
Chris@0 390
Chris@0 391 if (inGroup) {
Chris@0 392 dial->setFixedWidth(24);
Chris@0 393 dial->setFixedHeight(24);
Chris@493 394 m_groupLayouts[groupName]->addWidget
Chris@493 395 (dial, 0, m_groupLayouts[groupName]->columnCount());
Chris@0 396 } else {
Chris@0 397 dial->setFixedWidth(32);
Chris@0 398 dial->setFixedHeight(32);
Chris@0 399 m_layout->addWidget(dial, row, 1);
Chris@33 400 QLabel *label = new QLabel(m_mainWidget);
Chris@0 401 connect(dial, SIGNAL(valueChanged(int)),
Chris@0 402 label, SLOT(setNum(int)));
Chris@0 403 label->setNum(value);
Chris@0 404 m_layout->addWidget(label, row, 2);
Chris@0 405 }
Chris@0 406
Chris@0 407 m_propertyControllers[name] = dial;
Chris@0 408 }
Chris@0 409
Chris@55 410 if (dial->value() != value) {
Chris@55 411 dial->blockSignals(true);
Chris@55 412 dial->setValue(value);
Chris@55 413 dial->blockSignals(false);
Chris@55 414 }
Chris@0 415 break;
Chris@0 416 }
Chris@0 417
Chris@0 418 case PropertyContainer::ValueProperty:
Chris@100 419 case PropertyContainer::UnitsProperty:
Chris@285 420 case PropertyContainer::ColourProperty:
Chris@0 421 {
Chris@189 422 NotifyingComboBox *cb;
Chris@0 423
Chris@0 424 if (have) {
Chris@189 425 cb = dynamic_cast<NotifyingComboBox *>(m_propertyControllers[name]);
Chris@0 426 assert(cb);
Chris@0 427 } else {
Chris@0 428 #ifdef DEBUG_PROPERTY_BOX
Chris@0 429 std::cerr << "PropertyBox: creating new combobox" << std::endl;
Chris@0 430 #endif
Chris@0 431
Chris@189 432 cb = new NotifyingComboBox();
Chris@0 433 cb->setObjectName(name);
Chris@100 434 cb->setDuplicatesEnabled(false);
Chris@197 435 }
Chris@100 436
Chris@197 437 if (!have || rangeChanged) {
Chris@285 438
Chris@197 439 cb->blockSignals(true);
Chris@197 440 cb->clear();
Chris@285 441 cb->setEditable(false);
Chris@285 442
Chris@100 443 if (type == PropertyContainer::ValueProperty) {
Chris@285 444
Chris@100 445 for (int i = min; i <= max; ++i) {
Chris@100 446 cb->addItem(m_container->getPropertyValueLabel(name, i));
Chris@100 447 }
Chris@285 448
Chris@285 449 } else if (type == PropertyContainer::UnitsProperty) {
Chris@285 450
Chris@100 451 QStringList units = UnitDatabase::getInstance()->getKnownUnits();
Chris@100 452 for (int i = 0; i < units.size(); ++i) {
Chris@100 453 cb->addItem(units[i]);
Chris@100 454 }
Chris@285 455
Chris@100 456 cb->setEditable(true);
Chris@285 457
Chris@285 458 } else { // ColourProperty
Chris@290 459
Chris@290 460 //!!! should be a proper colour combobox class that
Chris@290 461 // manages its own Add New Colour entry...
Chris@285 462
Chris@285 463 ColourDatabase *db = ColourDatabase::getInstance();
Chris@285 464 for (size_t i = 0; i < db->getColourCount(); ++i) {
Chris@285 465 QString name = db->getColourName(i);
Chris@287 466 cb->addItem(db->getExamplePixmap(i, QSize(12, 12)), name);
Chris@285 467 }
Chris@285 468 cb->addItem(tr("Add New Colour..."));
Chris@285 469 }
Chris@285 470
Chris@197 471 cb->blockSignals(false);
Chris@280 472 if (cb->count() < 20 && cb->count() > cb->maxVisibleItems()) {
Chris@280 473 cb->setMaxVisibleItems(cb->count());
Chris@280 474 }
Chris@197 475 }
Chris@100 476
Chris@197 477 if (!have) {
Chris@0 478 connect(cb, SIGNAL(activated(int)),
Chris@0 479 this, SLOT(propertyControllerChanged(int)));
Chris@189 480 connect(cb, SIGNAL(mouseEntered()),
Chris@189 481 this, SLOT(mouseEnteredWidget()));
Chris@189 482 connect(cb, SIGNAL(mouseLeft()),
Chris@189 483 this, SLOT(mouseLeftWidget()));
Chris@100 484
Chris@0 485 if (inGroup) {
Chris@108 486 cb->setToolTip(propertyLabel);
Chris@493 487 m_groupLayouts[groupName]->addWidget
Chris@493 488 (cb, 0, m_groupLayouts[groupName]->columnCount());
Chris@0 489 } else {
Chris@0 490 m_layout->addWidget(cb, row, 1, 1, 2);
Chris@0 491 }
Chris@0 492 m_propertyControllers[name] = cb;
Chris@0 493 }
Chris@0 494
Chris@100 495 cb->blockSignals(true);
Chris@285 496 if (type == PropertyContainer::ValueProperty ||
Chris@285 497 type == PropertyContainer::ColourProperty) {
Chris@100 498 if (cb->currentIndex() != value) {
Chris@100 499 cb->setCurrentIndex(value);
Chris@100 500 }
Chris@100 501 } else {
Chris@100 502 QString unit = UnitDatabase::getInstance()->getUnitById(value);
Chris@100 503 if (cb->currentText() != unit) {
Chris@100 504 for (int i = 0; i < cb->count(); ++i) {
Chris@100 505 if (cb->itemText(i) == unit) {
Chris@100 506 cb->setCurrentIndex(i);
Chris@100 507 break;
Chris@100 508 }
Chris@100 509 }
Chris@100 510 }
Chris@100 511 }
Chris@100 512 cb->blockSignals(false);
Chris@0 513
Chris@0 514 #ifdef Q_WS_MAC
Chris@0 515 // Crashes on startup without this, for some reason
Chris@0 516 cb->setMinimumSize(QSize(10, 10));
Chris@0 517 #endif
Chris@0 518
Chris@0 519 break;
Chris@0 520 }
Chris@0 521
Chris@0 522 default:
Chris@0 523 break;
Chris@0 524 }
Chris@0 525 }
Chris@0 526
Chris@0 527 void
Chris@0 528 PropertyBox::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0 529 {
Chris@0 530 if (pc != m_container) return;
Chris@0 531
Chris@55 532 #ifdef DEBUG_PROPERTY_BOX
Chris@587 533 SVDEBUG << "PropertyBox::propertyContainerPropertyChanged" << endl;
Chris@55 534 #endif
Chris@55 535
Chris@0 536 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@0 537 size_t i;
Chris@0 538
Chris@0 539 blockSignals(true);
Chris@0 540
Chris@0 541 for (i = 0; i < properties.size(); ++i) {
Chris@0 542 updatePropertyEditor(properties[i]);
Chris@0 543 }
Chris@0 544
Chris@0 545 blockSignals(false);
Chris@0 546 }
Chris@0 547
Chris@0 548 void
Chris@249 549 PropertyBox::propertyContainerPropertyRangeChanged(PropertyContainer *)
Chris@197 550 {
Chris@197 551 blockSignals(true);
Chris@197 552
Chris@197 553 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@197 554 for (size_t i = 0; i < properties.size(); ++i) {
Chris@197 555 updatePropertyEditor(properties[i], true);
Chris@197 556 }
Chris@197 557
Chris@197 558 blockSignals(false);
Chris@197 559 }
Chris@197 560
Chris@197 561 void
Chris@100 562 PropertyBox::unitDatabaseChanged()
Chris@100 563 {
Chris@454 564 std::cerr << "PropertyBox[" << this << "]: unitDatabaseChanged" << std::endl;
Chris@100 565 blockSignals(true);
Chris@100 566
Chris@456 567 // std::cerr << "my container is " << m_container << std::endl;
Chris@456 568 // std::cerr << "my container's name is... " << std::endl;
Chris@584 569 // std::cerr << m_container->objectName() << std::endl;
Chris@456 570
Chris@100 571 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@100 572 for (size_t i = 0; i < properties.size(); ++i) {
Chris@285 573 if (m_container->getPropertyType(properties[i]) ==
Chris@285 574 PropertyContainer::UnitsProperty) {
Chris@285 575 updatePropertyEditor(properties[i]);
Chris@285 576 }
Chris@285 577 }
Chris@285 578
Chris@285 579 blockSignals(false);
Chris@285 580 }
Chris@285 581
Chris@285 582 void
Chris@285 583 PropertyBox::colourDatabaseChanged()
Chris@285 584 {
Chris@285 585 blockSignals(true);
Chris@285 586
Chris@285 587 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@285 588 for (size_t i = 0; i < properties.size(); ++i) {
Chris@285 589 if (m_container->getPropertyType(properties[i]) ==
Chris@285 590 PropertyContainer::ColourProperty) {
Chris@285 591 updatePropertyEditor(properties[i], true);
Chris@285 592 }
Chris@100 593 }
Chris@100 594
Chris@100 595 blockSignals(false);
Chris@100 596 }
Chris@100 597
Chris@100 598 void
Chris@335 599 PropertyBox::propertyControllerChanged(bool on)
Chris@335 600 {
Chris@335 601 propertyControllerChanged(on ? 1 : 0);
Chris@335 602 }
Chris@335 603
Chris@335 604 void
Chris@0 605 PropertyBox::propertyControllerChanged(int value)
Chris@0 606 {
Chris@0 607 QObject *obj = sender();
Chris@0 608 QString name = obj->objectName();
Chris@0 609
Chris@34 610 #ifdef DEBUG_PROPERTY_BOX
Chris@587 611 SVDEBUG << "PropertyBox::propertyControllerChanged(" << name << ", " << value << ")" << endl;
Chris@34 612 #endif
Chris@0 613
Chris@0 614 PropertyContainer::PropertyType type = m_container->getPropertyType(name);
Chris@100 615
Chris@376 616 Command *c = 0;
Chris@376 617
Chris@100 618 if (type == PropertyContainer::UnitsProperty) {
Chris@285 619
Chris@189 620 NotifyingComboBox *cb = dynamic_cast<NotifyingComboBox *>(obj);
Chris@100 621 if (cb) {
Chris@100 622 QString unit = cb->currentText();
Chris@376 623 c = m_container->getSetPropertyCommand
Chris@100 624 (name, UnitDatabase::getInstance()->getUnitId(unit));
Chris@100 625 }
Chris@285 626
Chris@285 627 } else if (type == PropertyContainer::ColourProperty) {
Chris@285 628
Chris@285 629 if (value == int(ColourDatabase::getInstance()->getColourCount())) {
Chris@285 630 addNewColour();
Chris@285 631 if (value == int(ColourDatabase::getInstance()->getColourCount())) {
Chris@285 632 propertyContainerPropertyChanged(m_container);
Chris@285 633 return;
Chris@285 634 }
Chris@285 635 }
Chris@376 636 c = m_container->getSetPropertyCommand(name, value);
Chris@285 637
Chris@100 638 } else if (type != PropertyContainer::InvalidProperty) {
Chris@285 639
Chris@376 640 c = m_container->getSetPropertyCommand(name, value);
Chris@0 641 }
Chris@376 642
Chris@376 643 if (c) CommandHistory::getInstance()->addCommand(c, true, true);
Chris@218 644
Chris@218 645 updateContextHelp(obj);
Chris@0 646 }
Chris@285 647
Chris@285 648 void
Chris@285 649 PropertyBox::addNewColour()
Chris@285 650 {
Chris@285 651 QColor newColour = QColorDialog::getColor();
Chris@285 652 if (!newColour.isValid()) return;
Chris@285 653
Chris@285 654 ColourNameDialog dialog(tr("Name New Colour"),
Chris@361 655 tr("Enter a name for the new colour:"),
Chris@361 656 newColour, newColour.name(), this);
Chris@285 657 dialog.showDarkBackgroundCheckbox(tr("Prefer black background for this colour"));
Chris@285 658 if (dialog.exec() == QDialog::Accepted) {
Chris@285 659 //!!! command
Chris@285 660 ColourDatabase *db = ColourDatabase::getInstance();
Chris@285 661 int index = db->addColour(newColour, dialog.getColourName());
Chris@285 662 db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked());
Chris@285 663 }
Chris@285 664 }
Chris@377 665
Chris@377 666 void
Chris@377 667 PropertyBox::playAudibleChanged(bool audible)
Chris@377 668 {
Chris@377 669 m_playButton->setState(audible);
Chris@377 670 }
Chris@377 671
Chris@377 672 void
Chris@377 673 PropertyBox::playAudibleButtonChanged(bool audible)
Chris@377 674 {
Chris@377 675 PlayParameters *params = m_container->getPlayParameters();
Chris@377 676 if (!params) return;
Chris@377 677
Chris@377 678 if (params->isPlayAudible() != audible) {
Chris@377 679 PlayParameterRepository::EditCommand *command =
Chris@377 680 new PlayParameterRepository::EditCommand(params);
Chris@377 681 command->setPlayAudible(audible);
Chris@377 682 CommandHistory::getInstance()->addCommand(command, true, true);
Chris@377 683 }
Chris@377 684 }
Chris@0 685
Chris@34 686 void
Chris@34 687 PropertyBox::playGainChanged(float gain)
Chris@34 688 {
Chris@34 689 int dialValue = lrint(log10(gain) * 20.0);
Chris@34 690 if (dialValue < -50) dialValue = -50;
Chris@34 691 if (dialValue > 50) dialValue = 50;
Chris@34 692 emit changePlayGainDial(dialValue);
Chris@34 693 }
Chris@34 694
Chris@34 695 void
Chris@34 696 PropertyBox::playGainDialChanged(int dialValue)
Chris@34 697 {
Chris@218 698 QObject *obj = sender();
Chris@377 699
Chris@377 700 PlayParameters *params = m_container->getPlayParameters();
Chris@377 701 if (!params) return;
Chris@377 702
Chris@34 703 float gain = pow(10, float(dialValue) / 20.0);
Chris@377 704
Chris@377 705 if (params->getPlayGain() != gain) {
Chris@377 706 PlayParameterRepository::EditCommand *command =
Chris@377 707 new PlayParameterRepository::EditCommand(params);
Chris@377 708 command->setPlayGain(gain);
Chris@377 709 CommandHistory::getInstance()->addCommand(command, true, true);
Chris@377 710 }
Chris@377 711
Chris@218 712 updateContextHelp(obj);
Chris@34 713 }
Chris@34 714
Chris@34 715 void
Chris@34 716 PropertyBox::playPanChanged(float pan)
Chris@34 717 {
Chris@34 718 int dialValue = lrint(pan * 50.0);
Chris@34 719 if (dialValue < -50) dialValue = -50;
Chris@34 720 if (dialValue > 50) dialValue = 50;
Chris@34 721 emit changePlayPanDial(dialValue);
Chris@34 722 }
Chris@34 723
Chris@34 724 void
Chris@34 725 PropertyBox::playPanDialChanged(int dialValue)
Chris@34 726 {
Chris@218 727 QObject *obj = sender();
Chris@377 728
Chris@377 729 PlayParameters *params = m_container->getPlayParameters();
Chris@377 730 if (!params) return;
Chris@377 731
Chris@34 732 float pan = float(dialValue) / 50.0;
Chris@34 733 if (pan < -1.0) pan = -1.0;
Chris@34 734 if (pan > 1.0) pan = 1.0;
Chris@377 735
Chris@377 736 if (params->getPlayPan() != pan) {
Chris@377 737 PlayParameterRepository::EditCommand *command =
Chris@377 738 new PlayParameterRepository::EditCommand(params);
Chris@377 739 command->setPlayPan(pan);
Chris@377 740 CommandHistory::getInstance()->addCommand(command, true, true);
Chris@377 741 }
Chris@377 742
Chris@218 743 updateContextHelp(obj);
Chris@34 744 }
Chris@0 745
Chris@63 746 void
Chris@63 747 PropertyBox::editPlugin()
Chris@63 748 {
Chris@63 749 //!!! should probably just emit and let something else do this
Chris@63 750
Chris@63 751 PlayParameters *params = m_container->getPlayParameters();
Chris@63 752 if (!params) return;
Chris@63 753
Chris@63 754 QString pluginId = params->getPlayPluginId();
Chris@63 755 QString configurationXml = params->getPlayPluginConfiguration();
Chris@377 756
Chris@377 757 PlayParameterRepository::EditCommand *command =
Chris@377 758 new PlayParameterRepository::EditCommand(params);
Chris@63 759
Chris@63 760 RealTimePluginFactory *factory =
Chris@63 761 RealTimePluginFactory::instanceFor(pluginId);
Chris@63 762 if (!factory) return;
Chris@63 763
Chris@63 764 RealTimePluginInstance *instance =
Chris@63 765 factory->instantiatePlugin(pluginId, 0, 0, 48000, 1024, 1);
Chris@63 766 if (!instance) return;
Chris@63 767
Chris@71 768 PluginXml(instance).setParametersFromXml(configurationXml);
Chris@63 769
Chris@163 770 PluginParameterDialog *dialog = new PluginParameterDialog(instance);
Chris@64 771 connect(dialog, SIGNAL(pluginConfigurationChanged(QString)),
Chris@64 772 this, SLOT(pluginConfigurationChanged(QString)));
Chris@64 773
Chris@63 774 if (dialog->exec() == QDialog::Accepted) {
Chris@377 775 QString newConfiguration = PluginXml(instance).toXmlString();
Chris@377 776 command->setPlayPluginConfiguration(newConfiguration);
Chris@377 777 CommandHistory::getInstance()->addCommand(command, true);
Chris@64 778 } else {
Chris@377 779 delete command;
Chris@64 780 // restore in case we mucked about with the configuration
Chris@64 781 // as a consequence of signals from the dialog
Chris@64 782 params->setPlayPluginConfiguration(configurationXml);
Chris@63 783 }
Chris@63 784
Chris@63 785 delete dialog;
Chris@63 786 delete instance;
Chris@63 787 }
Chris@63 788
Chris@64 789 void
Chris@64 790 PropertyBox::pluginConfigurationChanged(QString configurationXml)
Chris@64 791 {
Chris@64 792 PlayParameters *params = m_container->getPlayParameters();
Chris@64 793 if (!params) return;
Chris@64 794
Chris@64 795 params->setPlayPluginConfiguration(configurationXml);
Chris@64 796 }
Chris@185 797
Chris@185 798 void
Chris@185 799 PropertyBox::layerVisibilityChanged(bool visible)
Chris@185 800 {
Chris@185 801 if (m_showButton) m_showButton->setState(visible);
Chris@185 802 }
Chris@189 803
Chris@189 804 void
Chris@189 805 PropertyBox::mouseEnteredWidget()
Chris@189 806 {
Chris@218 807 updateContextHelp(sender());
Chris@218 808 }
Chris@218 809
Chris@218 810 void
Chris@218 811 PropertyBox::updateContextHelp(QObject *o)
Chris@218 812 {
Chris@218 813 QWidget *w = dynamic_cast<QWidget *>(o);
Chris@189 814 if (!w) return;
Chris@218 815
Chris@189 816 if (!m_container) return;
Chris@190 817 QString cname = m_container->getPropertyContainerName();
Chris@189 818 if (cname == "") return;
Chris@189 819
Chris@189 820 QString wname = w->objectName();
Chris@189 821
Chris@218 822 QString extraText;
Chris@218 823 AudioDial *dial = dynamic_cast<AudioDial *>(w);
Chris@218 824 if (dial) {
Chris@218 825 float mv = dial->mappedValue();
Chris@218 826 QString unit = "";
Chris@218 827 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit();
Chris@218 828 if (unit != "") {
Chris@218 829 extraText = tr(" (current value: %1%2)").arg(mv).arg(unit);
Chris@218 830 } else {
Chris@218 831 extraText = tr(" (current value: %1)").arg(mv);
Chris@218 832 }
Chris@218 833 }
Chris@218 834
Chris@189 835 if (w == m_showButton) {
Chris@190 836 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname));
Chris@189 837 } else if (w == m_playButton) {
Chris@190 838 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname));
Chris@189 839 } else if (wname == "") {
Chris@189 840 return;
Chris@335 841 } else if (dynamic_cast<QAbstractButton *>(w)) {
Chris@190 842 emit contextHelpChanged(tr("Toggle %1 property of %2")
Chris@189 843 .arg(wname).arg(cname));
Chris@189 844 } else {
Chris@218 845 emit contextHelpChanged(tr("Adjust %1 property of %2%3")
Chris@218 846 .arg(wname).arg(cname).arg(extraText));
Chris@189 847 }
Chris@189 848 }
Chris@189 849
Chris@189 850 void
Chris@189 851 PropertyBox::mouseLeftWidget()
Chris@189 852 {
Chris@218 853 if (!(QApplication::mouseButtons() & Qt::LeftButton)) {
Chris@218 854 emit contextHelpChanged("");
Chris@218 855 }
Chris@189 856 }
Chris@189 857
Chris@64 858