PropertyBox.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 "PropertyBox.h"
00017 #include "PluginParameterDialog.h"
00018 
00019 #include "base/PropertyContainer.h"
00020 #include "base/PlayParameters.h"
00021 #include "layer/Layer.h"
00022 #include "base/UnitDatabase.h"
00023 #include "base/ColourDatabase.h"
00024 #include "base/RangeMapper.h"
00025 
00026 #include "plugin/RealTimePluginFactory.h"
00027 #include "plugin/RealTimePluginInstance.h"
00028 #include "plugin/PluginXml.h"
00029 
00030 #include "AudioDial.h"
00031 #include "LEDButton.h"
00032 #include "IconLoader.h"
00033 
00034 #include "NotifyingCheckBox.h"
00035 #include "NotifyingComboBox.h"
00036 #include "NotifyingPushButton.h"
00037 #include "ColourNameDialog.h"
00038 
00039 #include <QGridLayout>
00040 #include <QHBoxLayout>
00041 #include <QVBoxLayout>
00042 #include <QPushButton>
00043 #include <QLabel>
00044 #include <QFrame>
00045 #include <QApplication>
00046 #include <QColorDialog>
00047 #include <QInputDialog>
00048 
00049 #include <cassert>
00050 #include <iostream>
00051 #include <cmath>
00052 
00053 //#define DEBUG_PROPERTY_BOX 1
00054 
00055 PropertyBox::PropertyBox(PropertyContainer *container) :
00056     m_container(container),
00057     m_showButton(0),
00058     m_playButton(0)
00059 {
00060 #ifdef DEBUG_PROPERTY_BOX
00061     std::cerr << "PropertyBox[" << this << "(\"" <<
00062         container->getPropertyContainerName().toStdString() << "\")]::PropertyBox" << std::endl;
00063 #endif
00064 
00065     m_mainBox = new QVBoxLayout;
00066     setLayout(m_mainBox);
00067 
00068 //    m_nameWidget = new QLabel;
00069 //    m_mainBox->addWidget(m_nameWidget);
00070 //    m_nameWidget->setText(container->objectName());
00071 
00072     m_mainWidget = new QWidget;
00073     m_mainBox->addWidget(m_mainWidget);
00074     m_mainBox->insertStretch(2, 10);
00075 
00076     m_viewPlayFrame = 0;
00077     populateViewPlayFrame();
00078 
00079     m_layout = new QGridLayout;
00080     m_layout->setMargin(0);
00081     m_mainWidget->setLayout(m_layout);
00082 
00083     PropertyContainer::PropertyList properties = m_container->getProperties();
00084 
00085     blockSignals(true);
00086 
00087     size_t i;
00088 
00089     for (i = 0; i < properties.size(); ++i) {
00090         updatePropertyEditor(properties[i]);
00091     }
00092 
00093     blockSignals(false);
00094 
00095     m_layout->setRowStretch(m_layout->rowCount(), 10);
00096 
00097     connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()),
00098             this, SLOT(unitDatabaseChanged()));
00099 
00100     connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()),
00101             this, SLOT(colourDatabaseChanged()));
00102 
00103 #ifdef DEBUG_PROPERTY_BOX
00104     std::cerr << "PropertyBox[" << this << "]::PropertyBox returning" << std::endl;
00105 #endif
00106 }
00107 
00108 PropertyBox::~PropertyBox()
00109 {
00110 #ifdef DEBUG_PROPERTY_BOX
00111     std::cerr << "PropertyBox[" << this << "]::~PropertyBox" << std::endl;
00112 #endif
00113 }
00114 
00115 void
00116 PropertyBox::populateViewPlayFrame()
00117 {
00118 #ifdef DEBUG_PROPERTY_BOX
00119     std::cerr << "PropertyBox(" << m_container << ")::populateViewPlayFrame" << std::endl;
00120 #endif
00121 
00122     if (m_viewPlayFrame) {
00123         delete m_viewPlayFrame;
00124         m_viewPlayFrame = 0;
00125     }
00126 
00127     if (!m_container) return;
00128 
00129     Layer *layer = dynamic_cast<Layer *>(m_container);
00130     if (layer) {
00131         disconnect(layer, SIGNAL(modelReplaced()),
00132                    this, SLOT(populateViewPlayFrame()));
00133         connect(layer, SIGNAL(modelReplaced()),
00134                 this, SLOT(populateViewPlayFrame()));
00135     }
00136 
00137     PlayParameters *params = m_container->getPlayParameters();
00138     if (!params && !layer) return;
00139 
00140     m_viewPlayFrame = new QFrame;
00141     m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
00142     m_mainBox->addWidget(m_viewPlayFrame);
00143 
00144     QHBoxLayout *layout = new QHBoxLayout;
00145     m_viewPlayFrame->setLayout(layout);
00146 
00147     layout->setMargin(layout->margin() / 2);
00148 
00149 #ifdef DEBUG_PROPERTY_BOX
00150     std::cerr << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName().toStdString() << ") params " << params << std::endl;
00151 #endif
00152 
00153     if (layer) {
00154         QLabel *showLabel = new QLabel(tr("Show"));
00155         layout->addWidget(showLabel);
00156         layout->setAlignment(showLabel, Qt::AlignVCenter);
00157 
00158         m_showButton = new LEDButton(Qt::blue);
00159         layout->addWidget(m_showButton);
00160         connect(m_showButton, SIGNAL(stateChanged(bool)),
00161                 this, SIGNAL(showLayer(bool)));
00162         connect(m_showButton, SIGNAL(mouseEntered()),
00163                 this, SLOT(mouseEnteredWidget()));
00164         connect(m_showButton, SIGNAL(mouseLeft()),
00165                 this, SLOT(mouseLeftWidget()));
00166         layout->setAlignment(m_showButton, Qt::AlignVCenter);
00167     }
00168     
00169     if (params) {
00170 
00171         QLabel *playLabel = new QLabel(tr("Play"));
00172         layout->addWidget(playLabel);
00173         layout->setAlignment(playLabel, Qt::AlignVCenter);
00174 
00175         m_playButton = new LEDButton(Qt::darkGreen);
00176         m_playButton->setState(!params->isPlayMuted());
00177         layout->addWidget(m_playButton);
00178         connect(m_playButton, SIGNAL(stateChanged(bool)),
00179                 params, SLOT(setPlayAudible(bool)));
00180         connect(m_playButton, SIGNAL(mouseEntered()),
00181                 this, SLOT(mouseEnteredWidget()));
00182         connect(m_playButton, SIGNAL(mouseLeft()),
00183                 this, SLOT(mouseLeftWidget()));
00184         connect(params, SIGNAL(playAudibleChanged(bool)),
00185                 m_playButton, SLOT(setState(bool)));
00186         layout->setAlignment(m_playButton, Qt::AlignVCenter);
00187 
00188         layout->insertStretch(-1, 10);
00189 
00190         if (params->getPlayPluginId() != "") {
00191             QPushButton *pluginButton = new QPushButton(QIcon(":icons/faders.png"), "");
00192             pluginButton->setFixedWidth(24);
00193             pluginButton->setFixedHeight(24);
00194             layout->addWidget(pluginButton);
00195             connect(pluginButton, SIGNAL(clicked()),
00196                     this, SLOT(editPlugin()));
00197         }
00198 
00199         AudioDial *gainDial = new AudioDial;
00200         layout->addWidget(gainDial);
00201         gainDial->setMeterColor(Qt::darkRed);
00202         gainDial->setMinimum(-50);
00203         gainDial->setMaximum(50);
00204         gainDial->setPageStep(1);
00205         gainDial->setFixedWidth(24);
00206         gainDial->setFixedHeight(24);
00207         gainDial->setNotchesVisible(false);
00208         gainDial->setDefaultValue(0);
00209         gainDial->setObjectName(tr("Playback Gain"));
00210         gainDial->setRangeMapper(new LinearRangeMapper
00211                                  (-50, 50, -25, 25, tr("dB")));
00212         gainDial->setShowToolTip(true);
00213         connect(gainDial, SIGNAL(valueChanged(int)),
00214                 this, SLOT(playGainDialChanged(int)));
00215         connect(params, SIGNAL(playGainChanged(float)),
00216                 this, SLOT(playGainChanged(float)));
00217         connect(this, SIGNAL(changePlayGain(float)),
00218                 params, SLOT(setPlayGain(float)));
00219         connect(this, SIGNAL(changePlayGainDial(int)),
00220                 gainDial, SLOT(setValue(int)));
00221         connect(gainDial, SIGNAL(mouseEntered()),
00222                 this, SLOT(mouseEnteredWidget()));
00223         connect(gainDial, SIGNAL(mouseLeft()),
00224                 this, SLOT(mouseLeftWidget()));
00225         layout->setAlignment(gainDial, Qt::AlignVCenter);
00226 
00227         AudioDial *panDial = new AudioDial;
00228         layout->addWidget(panDial);
00229         panDial->setMeterColor(Qt::darkGreen);
00230         panDial->setMinimum(-50);
00231         panDial->setMaximum(50);
00232         panDial->setPageStep(1);
00233         panDial->setFixedWidth(24);
00234         panDial->setFixedHeight(24);
00235         panDial->setNotchesVisible(false);
00236         panDial->setToolTip(tr("Playback Pan / Balance"));
00237         panDial->setDefaultValue(0);
00238         panDial->setObjectName(tr("Playback Pan / Balance"));
00239         panDial->setShowToolTip(true);
00240         connect(panDial, SIGNAL(valueChanged(int)),
00241                 this, SLOT(playPanDialChanged(int)));
00242         connect(params, SIGNAL(playPanChanged(float)),
00243                 this, SLOT(playPanChanged(float)));
00244         connect(this, SIGNAL(changePlayPan(float)),
00245                 params, SLOT(setPlayPan(float)));
00246         connect(this, SIGNAL(changePlayPanDial(int)),
00247                 panDial, SLOT(setValue(int)));
00248         connect(panDial, SIGNAL(mouseEntered()),
00249                 this, SLOT(mouseEnteredWidget()));
00250         connect(panDial, SIGNAL(mouseLeft()),
00251                 this, SLOT(mouseLeftWidget()));
00252         layout->setAlignment(panDial, Qt::AlignVCenter);
00253 
00254     } else {
00255 
00256         layout->insertStretch(-1, 10);
00257     }
00258 }
00259 
00260 void
00261 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name,
00262                                   bool rangeChanged)
00263 {
00264     PropertyContainer::PropertyType type = m_container->getPropertyType(name);
00265     int row = m_layout->rowCount();
00266 
00267     int min = 0, max = 0, value = 0, deflt = 0;
00268     value = m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
00269 
00270     bool have = (m_propertyControllers.find(name) !=
00271                  m_propertyControllers.end());
00272 
00273     QString groupName = m_container->getPropertyGroupName(name);
00274     QString propertyLabel = m_container->getPropertyLabel(name);
00275     QString iconName = m_container->getPropertyIconName(name);
00276 
00277 #ifdef DEBUG_PROPERTY_BOX
00278     std::cerr << "PropertyBox[" << this
00279               << "(\"" << m_container->getPropertyContainerName().toStdString()
00280               << "\")]";
00281     std::cerr << "::updatePropertyEditor(\"" << name.toStdString() << "\"):";
00282     std::cerr << " value " << value << ", have " << have << ", group \""
00283               << groupName.toStdString() << "\"" << std::endl;
00284 #endif
00285 
00286     bool inGroup = (groupName != QString());
00287 
00288     if (!have) {
00289         if (inGroup) {
00290             if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
00291 #ifdef DEBUG_PROPERTY_BOX
00292                 std::cerr << "PropertyBox: adding label \"" << groupName.toStdString() << "\" and frame for group for \"" << name.toStdString() << "\"" << std::endl;
00293 #endif
00294                 m_layout->addWidget(new QLabel(groupName, m_mainWidget), row, 0);
00295                 QFrame *frame = new QFrame(m_mainWidget);
00296                 m_layout->addWidget(frame, row, 1, 1, 2);
00297                 m_groupLayouts[groupName] = new QHBoxLayout;
00298                 m_groupLayouts[groupName]->setMargin(0);
00299                 frame->setLayout(m_groupLayouts[groupName]);
00300             }
00301         } else {
00302 #ifdef DEBUG_PROPERTY_BOX 
00303             std::cerr << "PropertyBox: adding label \"" << propertyLabel.toStdString() << "\"" << std::endl;
00304 #endif
00305             m_layout->addWidget(new QLabel(propertyLabel, m_mainWidget), row, 0);
00306         }
00307     }
00308 
00309     switch (type) {
00310 
00311     case PropertyContainer::ToggleProperty:
00312     {
00313         QAbstractButton *button = 0;
00314 
00315         if (have) {
00316             button = dynamic_cast<QAbstractButton *>(m_propertyControllers[name]);
00317             assert(button);
00318         } else {
00319 #ifdef DEBUG_PROPERTY_BOX 
00320             std::cerr << "PropertyBox: creating new checkbox" << std::endl;
00321 #endif
00322             if (iconName != "") {
00323                 button = new NotifyingPushButton();
00324                 button->setCheckable(true);
00325                 QIcon icon(IconLoader().load(iconName));
00326                 button->setIcon(icon);
00327                 button->setObjectName(name);
00328                 button->setFixedSize(QSize(18, 18));
00329             } else {
00330                 button = new NotifyingCheckBox();
00331                 button->setObjectName(name);
00332             }
00333             connect(button, SIGNAL(toggled(bool)),
00334                     this, SLOT(propertyControllerChanged(bool)));
00335             connect(button, SIGNAL(mouseEntered()),
00336                     this, SLOT(mouseEnteredWidget()));
00337             connect(button, SIGNAL(mouseLeft()),
00338                     this, SLOT(mouseLeftWidget()));
00339             if (inGroup) {
00340                 button->setToolTip(propertyLabel);
00341                 m_groupLayouts[groupName]->addWidget(button);
00342             } else {
00343                 m_layout->addWidget(button, row, 1, 1, 2);
00344             }
00345             m_propertyControllers[name] = button;
00346         }
00347 
00348         if (button->isChecked() != (value > 0)) {
00349             button->blockSignals(true);
00350             button->setChecked(value > 0);
00351             button->blockSignals(false);
00352         }
00353         break;
00354     }
00355 
00356     case PropertyContainer::RangeProperty:
00357     {
00358         AudioDial *dial;
00359 
00360         if (have) {
00361             dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]);
00362             assert(dial);
00363             if (rangeChanged) {
00364                 dial->blockSignals(true);
00365                 dial->setMinimum(min);
00366                 dial->setMaximum(max);
00367                 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name));
00368                 dial->blockSignals(false);
00369             }
00370                 
00371         } else {
00372 #ifdef DEBUG_PROPERTY_BOX 
00373             std::cerr << "PropertyBox: creating new dial" << std::endl;
00374 #endif
00375             dial = new AudioDial();
00376             dial->setObjectName(name);
00377             dial->setMinimum(min);
00378             dial->setMaximum(max);
00379             dial->setPageStep(1);
00380             dial->setNotchesVisible((max - min) <= 12);
00381             dial->setDefaultValue(deflt);
00382             dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name));
00383             dial->setShowToolTip(true);
00384             connect(dial, SIGNAL(valueChanged(int)),
00385                     this, SLOT(propertyControllerChanged(int)));
00386             connect(dial, SIGNAL(mouseEntered()),
00387                     this, SLOT(mouseEnteredWidget()));
00388             connect(dial, SIGNAL(mouseLeft()),
00389                     this, SLOT(mouseLeftWidget()));
00390 
00391             if (inGroup) {
00392                 dial->setFixedWidth(24);
00393                 dial->setFixedHeight(24);
00394                 m_groupLayouts[groupName]->addWidget(dial);
00395             } else {
00396                 dial->setFixedWidth(32);
00397                 dial->setFixedHeight(32);
00398                 m_layout->addWidget(dial, row, 1);
00399                 QLabel *label = new QLabel(m_mainWidget);
00400                 connect(dial, SIGNAL(valueChanged(int)),
00401                         label, SLOT(setNum(int)));
00402                 label->setNum(value);
00403                 m_layout->addWidget(label, row, 2);
00404             }
00405 
00406             m_propertyControllers[name] = dial;
00407         }
00408 
00409         if (dial->value() != value) {
00410             dial->blockSignals(true);
00411             dial->setValue(value);
00412             dial->blockSignals(false);
00413         }
00414         break;
00415     }
00416 
00417     case PropertyContainer::ValueProperty:
00418     case PropertyContainer::UnitsProperty:
00419     case PropertyContainer::ColourProperty:
00420     {
00421         NotifyingComboBox *cb;
00422 
00423         if (have) {
00424             cb = dynamic_cast<NotifyingComboBox *>(m_propertyControllers[name]);
00425             assert(cb);
00426         } else {
00427 #ifdef DEBUG_PROPERTY_BOX 
00428             std::cerr << "PropertyBox: creating new combobox" << std::endl;
00429 #endif
00430 
00431             cb = new NotifyingComboBox();
00432             cb->setObjectName(name);
00433             cb->setDuplicatesEnabled(false);
00434         }
00435 
00436         if (!have || rangeChanged) {
00437 
00438             cb->blockSignals(true);
00439             cb->clear();
00440             cb->setEditable(false);
00441 
00442             if (type == PropertyContainer::ValueProperty) {
00443 
00444                 for (int i = min; i <= max; ++i) {
00445                     cb->addItem(m_container->getPropertyValueLabel(name, i));
00446                 }
00447 
00448             } else if (type == PropertyContainer::UnitsProperty) {
00449 
00450                 QStringList units = UnitDatabase::getInstance()->getKnownUnits();
00451                 for (int i = 0; i < units.size(); ++i) {
00452                     cb->addItem(units[i]);
00453                 }
00454 
00455                 cb->setEditable(true);
00456 
00457             } else { // ColourProperty
00458 
00460                 // manages its own Add New Colour entry...
00461                 
00462                 ColourDatabase *db = ColourDatabase::getInstance();
00463                 for (size_t i = 0; i < db->getColourCount(); ++i) {
00464                     QString name = db->getColourName(i);
00465                     cb->addItem(db->getExamplePixmap(i, QSize(12, 12)), name);
00466                 }
00467                 cb->addItem(tr("Add New Colour..."));
00468             }                
00469                 
00470             cb->blockSignals(false);
00471             if (cb->count() < 20 && cb->count() > cb->maxVisibleItems()) {
00472                 cb->setMaxVisibleItems(cb->count());
00473             }
00474         }
00475 
00476         if (!have) {
00477             connect(cb, SIGNAL(activated(int)),
00478                     this, SLOT(propertyControllerChanged(int)));
00479             connect(cb, SIGNAL(mouseEntered()),
00480                     this, SLOT(mouseEnteredWidget()));
00481             connect(cb, SIGNAL(mouseLeft()),
00482                     this, SLOT(mouseLeftWidget()));
00483 
00484             if (inGroup) {
00485                 cb->setToolTip(propertyLabel);
00486                 m_groupLayouts[groupName]->addWidget(cb);
00487             } else {
00488                 m_layout->addWidget(cb, row, 1, 1, 2);
00489             }
00490             m_propertyControllers[name] = cb;
00491         }
00492 
00493         cb->blockSignals(true);
00494         if (type == PropertyContainer::ValueProperty ||
00495             type == PropertyContainer::ColourProperty) {
00496             if (cb->currentIndex() != value) {
00497                 cb->setCurrentIndex(value);
00498             }
00499         } else {
00500             QString unit = UnitDatabase::getInstance()->getUnitById(value);
00501             if (cb->currentText() != unit) {
00502                 for (int i = 0; i < cb->count(); ++i) {
00503                     if (cb->itemText(i) == unit) {
00504                         cb->setCurrentIndex(i);
00505                         break;
00506                     }
00507                 }
00508             }
00509         }
00510         cb->blockSignals(false);
00511 
00512 #ifdef Q_WS_MAC
00513         // Crashes on startup without this, for some reason
00514         cb->setMinimumSize(QSize(10, 10));
00515 #endif
00516 
00517         break;
00518     }
00519 
00520     default:
00521         break;
00522     }
00523 }
00524 
00525 void
00526 PropertyBox::propertyContainerPropertyChanged(PropertyContainer *pc)
00527 {
00528     if (pc != m_container) return;
00529     
00530 #ifdef DEBUG_PROPERTY_BOX
00531     std::cerr << "PropertyBox::propertyContainerPropertyChanged" << std::endl;
00532 #endif
00533 
00534     PropertyContainer::PropertyList properties = m_container->getProperties();
00535     size_t i;
00536 
00537     blockSignals(true);
00538 
00539     for (i = 0; i < properties.size(); ++i) {
00540         updatePropertyEditor(properties[i]);
00541     }
00542 
00543     blockSignals(false);
00544 }
00545 
00546 void
00547 PropertyBox::propertyContainerPropertyRangeChanged(PropertyContainer *)
00548 {
00549     blockSignals(true);
00550 
00551     PropertyContainer::PropertyList properties = m_container->getProperties();
00552     for (size_t i = 0; i < properties.size(); ++i) {
00553         updatePropertyEditor(properties[i], true);
00554     }
00555 
00556     blockSignals(false);
00557 }    
00558 
00559 void
00560 PropertyBox::unitDatabaseChanged()
00561 {
00562     blockSignals(true);
00563 
00564     PropertyContainer::PropertyList properties = m_container->getProperties();
00565     for (size_t i = 0; i < properties.size(); ++i) {
00566         if (m_container->getPropertyType(properties[i]) ==
00567             PropertyContainer::UnitsProperty) {
00568             updatePropertyEditor(properties[i]);
00569         }
00570     }
00571 
00572     blockSignals(false);
00573 }    
00574 
00575 void
00576 PropertyBox::colourDatabaseChanged()
00577 {
00578     blockSignals(true);
00579 
00580     PropertyContainer::PropertyList properties = m_container->getProperties();
00581     for (size_t i = 0; i < properties.size(); ++i) {
00582         if (m_container->getPropertyType(properties[i]) ==
00583             PropertyContainer::ColourProperty) {
00584             updatePropertyEditor(properties[i], true);
00585         }
00586     }
00587 
00588     blockSignals(false);
00589 }    
00590 
00591 void
00592 PropertyBox::propertyControllerChanged(bool on)
00593 {
00594     propertyControllerChanged(on ? 1 : 0);
00595 }
00596 
00597 void
00598 PropertyBox::propertyControllerChanged(int value)
00599 {
00600     QObject *obj = sender();
00601     QString name = obj->objectName();
00602 
00603 #ifdef DEBUG_PROPERTY_BOX
00604     std::cerr << "PropertyBox::propertyControllerChanged(" << name.toStdString()
00605               << ", " << value << ")" << std::endl;
00606 #endif
00607     
00608     PropertyContainer::PropertyType type = m_container->getPropertyType(name);
00609 
00610     if (type == PropertyContainer::UnitsProperty) {
00611 
00612         NotifyingComboBox *cb = dynamic_cast<NotifyingComboBox *>(obj);
00613         if (cb) {
00614             QString unit = cb->currentText();
00615             m_container->setPropertyWithCommand
00616                 (name, UnitDatabase::getInstance()->getUnitId(unit));
00617         }
00618 
00619     } else if (type == PropertyContainer::ColourProperty) {
00620 
00621         if (value == int(ColourDatabase::getInstance()->getColourCount())) {
00622             addNewColour();
00623             if (value == int(ColourDatabase::getInstance()->getColourCount())) {
00624                 propertyContainerPropertyChanged(m_container);
00625                 return;
00626             }
00627         }
00628         m_container->setPropertyWithCommand(name, value);
00629 
00630     } else if (type != PropertyContainer::InvalidProperty) {
00631 
00632         m_container->setPropertyWithCommand(name, value);
00633     }
00634     
00635     updateContextHelp(obj);
00636 }
00637 
00638 void
00639 PropertyBox::addNewColour()
00640 {
00641     QColor newColour = QColorDialog::getColor();
00642     if (!newColour.isValid()) return;
00643 
00644     ColourNameDialog dialog(tr("Name New Colour"),
00645                             tr("Enter a name for the new colour:"),
00646                             newColour, newColour.name(), this);
00647     dialog.showDarkBackgroundCheckbox(tr("Prefer black background for this colour"));
00648     if (dialog.exec() == QDialog::Accepted) {
00650         ColourDatabase *db = ColourDatabase::getInstance();
00651         int index = db->addColour(newColour, dialog.getColourName());
00652         db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked());
00653     }
00654 }
00655     
00656 void
00657 PropertyBox::playGainChanged(float gain)
00658 {
00659     int dialValue = lrint(log10(gain) * 20.0);
00660     if (dialValue < -50) dialValue = -50;
00661     if (dialValue >  50) dialValue =  50;
00662     emit changePlayGainDial(dialValue);
00663 }
00664 
00665 void
00666 PropertyBox::playGainDialChanged(int dialValue)
00667 {
00668     QObject *obj = sender();
00669     float gain = pow(10, float(dialValue) / 20.0);
00670     emit changePlayGain(gain);
00671     updateContextHelp(obj);
00672 }
00673     
00674 void
00675 PropertyBox::playPanChanged(float pan)
00676 {
00677     int dialValue = lrint(pan * 50.0);
00678     if (dialValue < -50) dialValue = -50;
00679     if (dialValue >  50) dialValue =  50;
00680     emit changePlayPanDial(dialValue);
00681 }
00682 
00683 void
00684 PropertyBox::playPanDialChanged(int dialValue)
00685 {
00686     QObject *obj = sender();
00687     float pan = float(dialValue) / 50.0;
00688     if (pan < -1.0) pan = -1.0;
00689     if (pan >  1.0) pan =  1.0;
00690     emit changePlayPan(pan);
00691     updateContextHelp(obj);
00692 }
00693 
00694 void
00695 PropertyBox::editPlugin()
00696 {
00698 
00699     PlayParameters *params = m_container->getPlayParameters();
00700     if (!params) return;
00701 
00702     QString pluginId = params->getPlayPluginId();
00703     QString configurationXml = params->getPlayPluginConfiguration();
00704     
00705     RealTimePluginFactory *factory =
00706         RealTimePluginFactory::instanceFor(pluginId);
00707     if (!factory) return;
00708 
00709     RealTimePluginInstance *instance =
00710         factory->instantiatePlugin(pluginId, 0, 0, 48000, 1024, 1);
00711     if (!instance) return;
00712 
00713     PluginXml(instance).setParametersFromXml(configurationXml);
00714 
00715     PluginParameterDialog *dialog = new PluginParameterDialog(instance);
00716     connect(dialog, SIGNAL(pluginConfigurationChanged(QString)),
00717             this, SLOT(pluginConfigurationChanged(QString)));
00718 
00719     if (dialog->exec() == QDialog::Accepted) {
00720         params->setPlayPluginConfiguration(PluginXml(instance).toXmlString());
00721     } else {
00722         // restore in case we mucked about with the configuration
00723         // as a consequence of signals from the dialog
00724         params->setPlayPluginConfiguration(configurationXml);
00725     }
00726 
00727     delete dialog;
00728     delete instance;
00729 }
00730 
00731 void
00732 PropertyBox::pluginConfigurationChanged(QString configurationXml)
00733 {
00734     PlayParameters *params = m_container->getPlayParameters();
00735     if (!params) return;
00736 
00737     params->setPlayPluginConfiguration(configurationXml);
00738 }    
00739 
00740 void
00741 PropertyBox::layerVisibilityChanged(bool visible)
00742 {
00743     if (m_showButton) m_showButton->setState(visible);
00744 }
00745 
00746 void
00747 PropertyBox::mouseEnteredWidget()
00748 {
00749     updateContextHelp(sender());
00750 }
00751 
00752 void
00753 PropertyBox::updateContextHelp(QObject *o)
00754 {
00755     QWidget *w = dynamic_cast<QWidget *>(o);
00756     if (!w) return;
00757 
00758     if (!m_container) return;
00759     QString cname = m_container->getPropertyContainerName();
00760     if (cname == "") return;
00761 
00762     QString wname = w->objectName();
00763 
00764     QString extraText;
00765     AudioDial *dial = dynamic_cast<AudioDial *>(w);
00766     if (dial) {
00767         float mv = dial->mappedValue();
00768         QString unit = "";
00769         if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit();
00770         if (unit != "") {
00771             extraText = tr(" (current value: %1%2)").arg(mv).arg(unit);
00772         } else {
00773             extraText = tr(" (current value: %1)").arg(mv);
00774         }
00775     }
00776 
00777     if (w == m_showButton) {
00778         emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname));
00779     } else if (w == m_playButton) {
00780         emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname));
00781     } else if (wname == "") {
00782         return;
00783     } else if (dynamic_cast<QAbstractButton *>(w)) {
00784         emit contextHelpChanged(tr("Toggle %1 property of %2")
00785                                 .arg(wname).arg(cname));
00786     } else {
00787         emit contextHelpChanged(tr("Adjust %1 property of %2%3")
00788                                 .arg(wname).arg(cname).arg(extraText));
00789     }
00790 }
00791 
00792 void
00793 PropertyBox::mouseLeftWidget()
00794 {
00795     if (!(QApplication::mouseButtons() & Qt::LeftButton)) {
00796         emit contextHelpChanged("");
00797     }
00798 }
00799 
00800 

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