Example #1
0
PasteUndoCommand::PasteUndoCommand(const KnobGuiPtr& knob,
                                   KnobClipBoardType type,
                                   int fromDimension,
                                   int targetDimension,
                                   const KnobPtr& fromKnob)
    : QUndoCommand(0)
    , _imp( new PasteUndoCommandPrivate() )
{
    _imp->knob = knob;
    _imp->type = type;
    _imp->fromDimension = fromDimension;
    _imp->targetDimension = targetDimension;
    _imp->fromKnob = fromKnob;

    {
        std::ostringstream ss;
        {
            try {
                boost::archive::xml_oarchive oArchive(ss);
                _imp->originalSerialization->initialize( knob->getKnob() );
                oArchive << boost::serialization::make_nvp("KnobClipboard", *_imp->originalSerialization);
            } catch (...) {
                assert(false);
            }
        }
        _imp->originalSerialization.reset(new KnobSerialization);
        std::string str = ss.str();
        {
            try {
                std::stringstream ss(str);
                boost::archive::xml_iarchive iArchive(ss);
                iArchive >> boost::serialization::make_nvp("KnobClipboard", *_imp->originalSerialization);
            } catch (...) {
                assert(false);
            }
        }
    }
    assert( _imp->originalSerialization->getKnob() );

    assert(knob);
    assert( _imp->targetDimension >= -1 && _imp->targetDimension < _imp->knob.lock()->getKnob()->getDimension() );
    assert( _imp->fromDimension >= -1 && _imp->fromDimension < _imp->fromKnob->getDimension() );
    QString text;
    switch (type) {
    case eKnobClipBoardTypeCopyAnim:
        text = tr("Paste Animation to %1");
        break;
    case eKnobClipBoardTypeCopyValue:
        text = tr("Paste Value to %1");
        break;
    case eKnobClipBoardTypeCopyLink:
        text = tr("Paste Link to %1");
        break;
    }
    setText( text.arg( QString::fromUtf8( knob->getKnob()->getLabel().c_str() ) ) );
}
Example #2
0
MultipleKnobEditsUndoCommand::MultipleKnobEditsUndoCommand(const KnobGuiPtr& knob,
                                                           ValueChangedReasonEnum reason,
                                                           bool createNew,
                                                           bool setKeyFrame,
                                                           const Variant & value,
                                                           int dimension,
                                                           double time)
    : QUndoCommand()
    , knobs()
    , createNew(createNew)
    , firstRedoCalled(false)
    , _reason(reason)
{
    assert(knob);
    std::list<ValueToSet>& vlist = knobs[knob];
    ValueToSet v;
    v.newValue = value;
    v.dimension = dimension;
    assert(dimension != -1);
    v.time = time;
    v.setKeyFrame = setKeyFrame;
    v.setValueRetCode = -1;
    vlist.push_back(v);

    KnobHolder* holder = knob->getKnob()->getHolder();
    EffectInstance* effect = dynamic_cast<EffectInstance*>(holder);
    QString holderName;
    if (effect) {
        holderName = QString::fromUtf8( effect->getNode()->getLabel().c_str() );
    }

    setText( tr("Multiple edits for %1").arg(holderName) );
}
Example #3
0
void
KnobGuiGroup::setCheckedInternal(bool checked,
                                 bool userRequested)
{
    if (checked == _checked) {
        return;
    }
    _checked = checked;

    if (userRequested) {
        KnobGroupPtr knob = _knob.lock();
        if (knob) {
            knob->setValue(checked);
        }
    }

    //getGui()->getPropertiesBin()->setUpdatesEnabled(false);
    for (std::list<KnobGuiWPtr>::iterator it = _children.begin(); it != _children.end(); ++it) {
        KnobGuiPtr knob = it->lock();
        if (!knob) {
            continue;
        }
        if (!checked) {
            knob->hide();
        } else if ( !knob->getKnob()->getIsSecret() ) {
            knob->show();
        }
    }
    //getGui()->getPropertiesBin()->setUpdatesEnabled(true);
}
void
DSRemoveKeysCommand::addOrRemoveKeyframe(bool add)
{
    std::set<KnobGuiPtr> knobsSet;
    for (std::vector<DopeSheetKey>::iterator it = _keys.begin(); it != _keys.end(); ++it) {
        DopeSheetKey selected = (*it);
        DSKnobPtr knobContext = selected.context.lock();
        if (!knobContext) {
            continue;
        }

        KnobGuiPtr knobGui = knobContext->getKnobGui();
        assert(knobGui);

        std::pair<std::set<KnobGuiPtr>::iterator,bool> ok = knobsSet.insert(knobGui);
        if (ok.second) {
            knobGui->getKnob()->beginChanges();
        }
        if (add) {
            knobGui->setKeyframe( selected.key.getTime(), selected.key, knobContext->getDimension(), ViewIdx(0) );
        } else {
            knobGui->removeKeyFrame( selected.key.getTime(), knobContext->getDimension(), ViewIdx(0) );
            knobContext->getTreeItem()->setSelected(false);
        }
    }

    for (std::set<KnobGuiPtr>::iterator it = knobsSet.begin(); it != knobsSet.end(); ++it) {
        (*it)->getKnob()->endChanges();
    }

    _model->refreshSelectionBboxAndRedrawView();
}
Example #5
0
KnobGuiColor::KnobGuiColor(const KnobGuiPtr& knobUI, ViewIdx view)
    : KnobGuiValue(knobUI, view)
    , _knob( toKnobColor(knobUI->getKnob()) )
    , _colorLabel(0)
    , _colorDialogButton(0)
    , _useSimplifiedUI(false)
    , _uiColorspaceLut(0)
    , _internalColorspaceLut(0)
{
    KnobColorPtr knob = _knob.lock();
    if (!knob) {
        return;
    }
    _useSimplifiedUI = knob && knob->isSimplified();
    if (!_useSimplifiedUI) {
        DimIdx singleDim;
        bool singleDimEnabled = knobUI->isSingleDimensionalEnabled(&singleDim);
        if (knobUI->getLayoutType() == KnobGui::eKnobLayoutTypeViewerUI && !singleDimEnabled) {
            _useSimplifiedUI = true;
        }
    }
    const std::string& uiName = knob->getUIColorspaceName();
    const std::string& internalName = knob->getInternalColorspaceName();
    _uiColorspaceLut = Color::LutManager::findLut(uiName);
    _internalColorspaceLut = Color::LutManager::findLut(internalName);
}
Example #6
0
KnobGuiGroup::KnobGuiGroup(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _checked(false)
    , _button(0)
    , _children()
    , _knob( toKnobGroup(knob->getKnob()) )
{
}
Example #7
0
KnobComboBox::KnobComboBox(const KnobGuiPtr& knob,
                           DimSpec dimension,
                           ViewIdx view,
                           QWidget* parent)
    : ComboBox(parent)
    , _knob(toKnobChoice(knob->getKnob()))
    , _dnd( KnobWidgetDnD::create(knob, dimension, view, this) )
    , _drawLinkedFrame(false)
{
}
LinkToKnobDialog::LinkToKnobDialog(const KnobGuiPtr& from,
                                   QWidget* parent)
    : QDialog(parent)
    , _imp( new LinkToKnobDialogPrivate(from) )
{
    _imp->mainLayout = new QVBoxLayout(this);

    _imp->firstLine = new QWidget(this);
    _imp->firstLineLayout = new QHBoxLayout(_imp->firstLine);

    _imp->mainLayout->addWidget(_imp->firstLine);

    _imp->buttons = new QDialogButtonBox(QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel),
                                         Qt::Horizontal, this);
    QObject::connect( _imp->buttons, SIGNAL(accepted()), this, SLOT(accept()) );
    QObject::connect( _imp->buttons, SIGNAL(rejected()), this, SLOT(reject()) );
    _imp->mainLayout->addWidget(_imp->buttons);

    _imp->selectNodeLabel = new Label(tr("Parent:"), _imp->firstLine);
    _imp->firstLineLayout->addWidget(_imp->selectNodeLabel);


    EffectInstance* isEffect = dynamic_cast<EffectInstance*>( from->getKnob()->getHolder() );
    assert(isEffect);
    if (!isEffect) {
        throw std::logic_error("");
    }
    boost::shared_ptr<NodeCollection> group = isEffect->getNode()->getGroup();
    group->getActiveNodes(&_imp->allNodes);
    NodeGroup* isGroup = dynamic_cast<NodeGroup*>( group.get() );
    if (isGroup) {
        _imp->allNodes.push_back( isGroup->getNode() );
    }
    QStringList nodeNames;
    for (NodesList::iterator it = _imp->allNodes.begin(); it != _imp->allNodes.end(); ++it) {
        QString name = QString::fromUtf8( (*it)->getLabel().c_str() );
        nodeNames.push_back(name);
        //_imp->nodeSelectionCombo->addItem(name);
    }
    nodeNames.sort();
    _imp->nodeSelectionCombo = new CompleterLineEdit(nodeNames, nodeNames, false, this);
    _imp->nodeSelectionCombo->setToolTip( GuiUtils::convertFromPlainText(tr("Input the name of a node in the current project."), Qt::WhiteSpaceNormal) );
    _imp->firstLineLayout->addWidget(_imp->nodeSelectionCombo);


    _imp->nodeSelectionCombo->setFocus(Qt::PopupFocusReason);
    QTimer::singleShot( 25, _imp->nodeSelectionCombo, SLOT(showCompleter()) );

    _imp->knobSelectionCombo = new ComboBox(_imp->firstLine);
    _imp->firstLineLayout->addWidget(_imp->knobSelectionCombo);

    QObject::connect( _imp->nodeSelectionCombo, SIGNAL(itemCompletionChosen()), this, SLOT(onNodeComboEditingFinished()) );

    _imp->firstLineLayout->addStretch();
}
Example #9
0
KnobGuiChoice::KnobGuiChoice(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _comboBox(0)
{
    KnobChoicePtr k = toKnobChoice(knob->getKnob());
    QObject::connect( k.get(), SIGNAL(populated()), this, SLOT(onEntriesPopulated()) );
    QObject::connect( k.get(), SIGNAL(entryAppended()), this, SLOT(onEntryAppended()) );
    QObject::connect( k.get(), SIGNAL(entriesReset()), this, SLOT(onEntriesReset()) );

    _knob = k;
}
Example #10
0
 void onSelectedKnobChanged()
 {
     if (!selectedKnob) {
         return;
     }
     KnobParametricPtr isParametric = toKnobParametric( selectedKnob->getKnob() );
     if (isParametric) {
         useAliasCheckBox->setChecked(true);
     }
     useAliasLabel->setEnabled(!isParametric);
     useAliasCheckBox->setEnabled(!isParametric);
 }
Example #11
0
 void onSelectedKnobChanged()
 {
     if (!selectedKnob) {
         return;
     }
     KnobParametric* isParametric = dynamic_cast<KnobParametric*>( selectedKnob->getKnob().get() );
     if (isParametric) {
         useAliasCheckBox->setChecked(true);
     }
     useAliasLabel->setEnabled(!isParametric);
     useAliasCheckBox->setEnabled(!isParametric);
 }
Example #12
0
void
ColorPickerLabel::setEnabledMode(bool enabled)
{
    setEnabled(enabled);
    if (!enabled && _pickingEnabled) {
        _pickingEnabled = false;
        setColor(_currentColor);
        if (_knob) {
            ViewIdx view = _knob->getView();
            KnobGuiPtr knobUI = _knob->getKnobGui();
            knobUI->getGui()->removeColorPicker( toKnobColor( knobUI->getKnob() ), view );
        }
    }
}
Example #13
0
KnobGuiFile::KnobGuiFile(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _lineEdit(0)
    , _openFileButton(0)
    , _reloadButton(0)
    , _lastOpened()
    , _lastModificationDates()
{
    KnobFilePtr k = toKnobFile(knob->getKnob());

    assert(k);
    QObject::connect( k.get(), SIGNAL(openFile()), this, SLOT(open_file()) );
    _knob = k;
}
Example #14
0
void
KnobGuiGroup::setEnabled()
{
    boost::shared_ptr<KnobGroup> knob = _knob.lock();
    bool enabled = knob->isEnabled(0)  && !knob->isSlave(0) && knob->getExpression(0).empty();

    if (_button) {
        _button->setEnabled(enabled);
    }
    if (enabled) {
        for (U32 i = 0; i < _childrenToEnable.size(); ++i) {
            for (U32 j = 0; j < _childrenToEnable[i].second.size(); ++j) {
                KnobGuiPtr k = _childrenToEnable[i].first.lock();
                if (!k) {
                    continue;
                }
                k->getKnob()->setEnabled(_childrenToEnable[i].second[j], true);
            }
        }
    } else {
        _childrenToEnable.clear();
        for (std::list<KnobGuiWPtr>::iterator it = _children.begin(); it != _children.end(); ++it) {
            KnobGuiPtr k = it->lock();
            if (!k) {
                continue;
            }
            std::vector<int> dimensions;
            for (int j = 0; j < k->getKnob()->getDimension(); ++j) {
                if ( k->getKnob()->isEnabled(j) ) {
                    k->getKnob()->setEnabled(j, false);
                    dimensions.push_back(j);
                }
            }
            _childrenToEnable.push_back( std::make_pair(*it, dimensions) );
        }
    }
}
Example #15
0
void
KnobGuiGroup::setCheckedInternal(bool checked, bool userRequested)
{
    if (checked == _checked) {
        return;
    }
    _checked = checked;
    
    if (userRequested) {
        boost::shared_ptr<KnobGroup> knob = _knob.lock();
        if (knob) {
            knob->setValue(checked, ViewSpec::all(), 0, eValueChangedReasonUserEdited, 0);
        }
    }
    
    ///get the current index of the group knob in the layout, and reinsert
    ///the children back with an offset relative to the group.
    int realIndexInLayout = getActualIndexInLayout();
    int startChildIndex = realIndexInLayout + 1;
    //getGui()->getPropertiesBin()->setUpdatesEnabled(false);
    for (std::list<KnobGuiWPtr>::iterator it = _children.begin(); it != _children.end(); ++it) {
        KnobGuiPtr knob = it->lock();
        if (!knob) {
            continue;
        }
        if (!checked) {
            knob->hide();
        } else if ( !knob->getKnob()->getIsSecret() ) {
            knob->show(startChildIndex);
            if ( knob->getKnob()->isNewLineActivated() ) {
                ++startChildIndex;
            }
        }
    }
    //getGui()->getPropertiesBin()->setUpdatesEnabled(true);
}
Example #16
0
std::string
KnobGuiWidgets::getDescriptionLabel() const
{
    std::string ret;
    KnobGuiPtr knob = getKnobGui();
    if (!knob) {
        return ret;
    }
    KnobIPtr internalKnob = knob->getKnob();
    if (!internalKnob) {
        return ret;
    }
    ret = internalKnob->getLabel();
    return ret;
}
Example #17
0
KnobGuiColor::KnobGuiColor(const KnobGuiPtr& knobUI, ViewIdx view)
    : KnobGuiValue(knobUI, view)
    , _knob( toKnobColor(knobUI->getKnob()) )
    , _colorLabel(0)
    , _colorDialogButton(0)
    , _useSimplifiedUI( _knob.lock()->isSimplified() )
{
    if (!_useSimplifiedUI) {
        DimIdx singleDim;
        bool singleDimEnabled = knobUI->isSingleDimensionalEnabled(&singleDim);
        if (knobUI->getLayoutType() == KnobGui::eKnobLayoutTypeViewerUI && !singleDimEnabled) {
            _useSimplifiedUI = true;
        }
    }
}
Example #18
0
KnobGuiString::KnobGuiString(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _lineEdit(0)
    , _label(0)
    , _container(0)
    , _mainLayout(0)
    , _textEdit(0)
    , _richTextOptions(0)
    , _richTextOptionsLayout(0)
    , _fontCombo(0)
    , _setBoldButton(0)
    , _setItalicButton(0)
    , _fontSizeSpinBox(0)
    , _fontColorButton(0)
{
    _knob = toKnobString(knob->getKnob());
}
Example #19
0
void
KnobSpinBox::focusInEvent(QFocusEvent* e)
{
    _dnd->focusIn();
    SpinBox::focusInEvent(e);


    //Set the expression so the user can edit it easily
    KnobGuiPtr k = knob.lock();
    if (!k) {
        return;
    }
    std::string expr = k->getKnob()->getExpression(dimension);
    if ( expr.empty() ) {
        return;
    } else {
        QLineEdit::setText( QString::fromUtf8( expr.c_str() ) );
        setCursorPosition(expr.size() - 1);
    }
}
Example #20
0
void
KnobGuiWidgets::enableRightClickMenu(const KnobGuiPtr& knob,
                                     QWidget* widget,
                                     DimSpec dimension,
                                     ViewSetSpec view)
{

    KnobIPtr internalKnob = knob->getKnob();
    if (!internalKnob) {
        return;
    }
    KnobSeparatorPtr sep = toKnobSeparator(internalKnob);
    KnobGroupPtr grp = toKnobGroup(internalKnob);
    if (sep || grp) {
        return;
    }

    widget->setProperty(KNOB_RIGHT_CLICK_DIM_PROPERTY, QVariant(dimension));
    widget->setProperty(KNOB_RIGHT_CLICK_VIEW_PROPERTY, QVariant(view));
    widget->setContextMenuPolicy(Qt::CustomContextMenu);
    QObject::connect( widget, SIGNAL(customContextMenuRequested(QPoint)), knob.get(), SLOT(onRightClickClicked(QPoint)) );
}
Example #21
0
KnobGuiBool::KnobGuiBool(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _checkBox(0)
{
    _knob = toKnobBool(knob->getKnob());
}
Example #22
0
KnobGuiSeparator::KnobGuiSeparator(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _line(0)
{
    _knob = toKnobSeparator(knob->getKnob());
}
Example #23
0
KnobGuiButton::KnobGuiButton(const KnobGuiPtr& knob, ViewIdx view)
    : KnobGuiWidgets(knob, view)
    , _button(0)
{
    _knob = toKnobButton(knob->getKnob());
}
Example #24
0
void
MultipleKnobEditsUndoCommand::redo()
{
    assert( !knobs.empty() );
    KnobHolder* holder = knobs.begin()->first.lock()->getKnob()->getHolder();
    if (holder) {
        holder->beginChanges();
    }

    ///this is the first redo command, set values
    for (ParamsMap::iterator it = knobs.begin(); it != knobs.end(); ++it) {
        KnobGuiPtr knobUI = it->first.lock();
        if (!knobUI) {
            continue;
        }
        KnobPtr knob = knobUI->getKnob();
        if (!knob) {
            continue;
        }
        knob->beginChanges();
        Knob<int>* isInt = dynamic_cast<Knob<int>*>( knob.get() );
        Knob<bool>* isBool = dynamic_cast<Knob<bool>*>( knob.get() );
        Knob<double>* isDouble = dynamic_cast<Knob<double>*>( knob.get() );
        Knob<std::string>* isString = dynamic_cast<Knob<std::string>*>( knob.get() );

        for (std::list<ValueToSet>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
            KeyFrame k;

            if (!firstRedoCalled) {
                if (isInt) {
                    it2->oldValue.setValue( isInt->getValueAtTime(it2->time, it2->dimension) );
                } else if (isBool) {
                    it2->oldValue.setValue( isBool->getValueAtTime(it2->time, it2->dimension) );
                } else if (isDouble) {
                    it2->oldValue.setValue( isDouble->getValueAtTime(it2->time, it2->dimension) );
                } else if (isString) {
                    it2->oldValue.setValue( isString->getValueAtTime(it2->time, it2->dimension) );
                }
            }

            if (it2->setKeyFrame) {
                bool keyAdded = false;
                bool refreshGui =  it2->time == knob->getHolder()->getApp()->getTimeLine()->currentFrame();
                if (isInt) {
                    keyAdded = knobUI->setValueAtTime<int>(it2->dimension, it2->newValue.toInt(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                } else if (isBool) {
                    keyAdded = knobUI->setValueAtTime<bool>(it2->dimension, it2->newValue.toBool(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                } else if (isDouble) {
                    keyAdded = knobUI->setValueAtTime<double>(it2->dimension, it2->newValue.toDouble(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                } else if (isString) {
                    keyAdded = knobUI->setValueAtTime<std::string>(it2->dimension, it2->newValue.toString().toStdString(), it2->time,
                                                                   ViewIdx(0), &k, refreshGui, _reason);
                } else {
                    assert(false);
                }
                it2->setValueRetCode = keyAdded ? KnobHelper::eValueChangedReturnCodeKeyframeAdded : KnobHelper::eValueChangedReturnCodeKeyframeModified;
            } else {
                if (isInt) {
                    it2->setValueRetCode = knobUI->setValue<int>(it2->dimension, it2->newValue.toInt(), &k, true, _reason);
                } else if (isBool) {
                    it2->setValueRetCode = knobUI->setValue<bool>(it2->dimension, it2->newValue.toBool(), &k, true, _reason);
                } else if (isDouble) {
                    it2->setValueRetCode = knobUI->setValue<double>(it2->dimension, it2->newValue.toDouble(), &k, true, _reason);
                } else if (isString) {
                    it2->setValueRetCode = knobUI->setValue<std::string>(it2->dimension, it2->newValue.toString().toStdString(),
                                                                         &k, true, _reason);
                } else {
                    assert(false);
                }
                if (!firstRedoCalled && !it2->setKeyFrame) {
                    it2->time = knob->getCurrentTime();
                }
            }
        }
        knob->endChanges();
    }

    if (holder) {
        holder->endChanges();
    }

    firstRedoCalled = true;
} // redo
Example #25
0
void
MultipleKnobEditsUndoCommand::undo()
{
    assert( !knobs.empty() );
    KnobHolder* holder = knobs.begin()->first.lock()->getKnob()->getHolder();
    if (holder) {
        holder->beginChanges();
    }

    for (ParamsMap::iterator it = knobs.begin(); it != knobs.end(); ++it) {
        KnobGuiPtr knobUI = it->first.lock();
        if (!knobUI) {
            continue;
        }
        KnobPtr knob = knobUI->getKnob();
        if (!knob) {
            continue;
        }
        knob->beginChanges();
        Knob<int>* isInt = dynamic_cast<Knob<int>*>( knob.get() );
        Knob<bool>* isBool = dynamic_cast<Knob<bool>*>( knob.get() );
        Knob<double>* isDouble = dynamic_cast<Knob<double>*>( knob.get() );
        Knob<std::string>* isString = dynamic_cast<Knob<std::string>*>( knob.get() );
        KeyFrame k;
        for (std::list<ValueToSet>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
            KnobHelper::ValueChangedReturnCodeEnum retCode = (KnobHelper::ValueChangedReturnCodeEnum)it2->setValueRetCode;

            if (retCode == KnobHelper::eValueChangedReturnCodeKeyframeAdded) {
                knobUI->removeKeyFrame( it2->time, it2->dimension, ViewIdx(0) );
            } else {
                if (it2->setKeyFrame) {
                    bool refreshGui =  it2->time == knob->getHolder()->getApp()->getTimeLine()->currentFrame();
                    if (isInt) {
                        knobUI->setValueAtTime<int>(it2->dimension, it2->oldValue.toInt(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                    } else if (isBool) {
                        knobUI->setValueAtTime<bool>(it2->dimension, it2->oldValue.toBool(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                    } else if (isDouble) {
                        knobUI->setValueAtTime<double>(it2->dimension, it2->oldValue.toDouble(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                    } else if (isString) {
                        knobUI->setValueAtTime<std::string>(it2->dimension, it2->oldValue.toString().toStdString(), it2->time, ViewIdx(0), &k, refreshGui, _reason);
                    } else {
                        assert(false);
                    }
                } else {
                    if (isInt) {
                        knobUI->setValue<int>(it2->dimension, it2->oldValue.toInt(), &k, true, _reason);
                    } else if (isBool) {
                        knobUI->setValue<bool>(it2->dimension, it2->oldValue.toBool(), &k, true, _reason);
                    } else if (isDouble) {
                        knobUI->setValue<double>(it2->dimension, it2->oldValue.toDouble(), &k, true, _reason);
                    } else if (isString) {
                        knobUI->setValue<std::string>(it2->dimension, it2->oldValue.toString().toStdString(),
                                                      &k, true, _reason);
                    } else {
                        assert(false);
                    }
                }
            }
        }
        knob->endChanges();
    }


    if (holder) {
        holder->endChanges();
    }
} // MultipleKnobEditsUndoCommand::undo