void KnobGui::onUnlinkActionTriggered() { QAction* action = qobject_cast<QAction*>( sender() ); if (!action) { return; } int dim = action->data().toInt(); KnobPtr thisKnob = getKnob(); int dims = thisKnob->getDimension(); KnobPtr aliasMaster = thisKnob->getAliasMaster(); if (aliasMaster) { thisKnob->setKnobAsAliasOfThis(aliasMaster, false); } else { thisKnob->beginChanges(); for (int i = 0; i < dims; ++i) { if ( (dim == -1) || (i == dim) ) { std::pair<int, KnobPtr > other = thisKnob->getMaster(i); thisKnob->onKnobUnSlaved(i); onKnobSlavedChanged(i, false); } } thisKnob->endChanges(); } getKnob()->getHolder()->getApp()->triggerAutoSave(); }
void KnobGui::setKeyframes(const std::vector<KeyFrame>& keys, int dimension, ViewSpec view) { KnobPtr knob = getKnob(); assert( knob->getHolder()->getApp() ); knob->beginChanges(); std::list<SequenceTime> times; for (std::size_t i = 0; i < keys.size(); ++i) { bool keyAdded = knob->onKeyFrameSet(keys[i].getTime(), view, keys[i], dimension); if (keyAdded) { times.push_back( keys[i].getTime() ); } } knob->endChanges(); Q_EMIT keyFrameSet(); if ( !knob->getIsSecret() && knob->isDeclaredByPlugin() ) { knob->getHolder()->getApp()->addMultipleKeyframeIndicatorsAdded(times, true); } }
void KnobGui::removeKeyframes(const std::vector<KeyFrame>& keys, int dimension, ViewSpec view) { KnobPtr knob = getKnob(); knob->beginChanges(); for (std::size_t i = 0; i < keys.size(); ++i) { knob->onKeyFrameRemoved(keys[i].getTime(), view, dimension); } knob->endChanges(); /*assert( knob->getHolder()->getApp() ); if ( !knob->getIsSecret() ) { std::list<SequenceTime> times; for (std::size_t i = 0; i < keys.size(); ++i) { times.push_back(keys[i].getTime()); } knob->getHolder()->getApp()->getTimeLine()->removeMultipleKeyframeIndicator(times, true); }*/ Q_EMIT keyFrameRemoved(); updateGUI(dimension); }
void KnobGui::linkTo(int dimension) { KnobPtr thisKnob = getKnob(); assert(thisKnob); EffectInstance* isEffect = dynamic_cast<EffectInstance*>( thisKnob->getHolder() ); if (!isEffect) { return; } for (int i = 0; i < thisKnob->getDimension(); ++i) { if ( (i == dimension) || (dimension == -1) ) { std::string expr = thisKnob->getExpression(dimension); if ( !expr.empty() ) { Dialogs::errorDialog( tr("Param Link").toStdString(), tr("This parameter already has an expression set, edit or clear it.").toStdString() ); return; } } } LinkToKnobDialog dialog( shared_from_this(), _imp->copyRightClickMenu->parentWidget() ); if ( dialog.exec() ) { KnobPtr otherKnob = dialog.getSelectedKnobs(); if (otherKnob) { if ( !thisKnob->isTypeCompatible(otherKnob) ) { Dialogs::errorDialog( tr("Param Link").toStdString(), tr("Types are incompatible!").toStdString() ); return; } for (int i = 0; i < thisKnob->getDimension(); ++i) { std::pair<int, KnobPtr > existingLink = thisKnob->getMaster(i); if (existingLink.second) { Dialogs::errorDialog( tr("Param Link").toStdString(), tr("Cannot link %1 because the knob is already linked to %2.") .arg( QString::fromUtf8( thisKnob->getLabel().c_str() ) ) .arg( QString::fromUtf8( existingLink.second->getLabel().c_str() ) ) .toStdString() ); return; } } EffectInstance* otherEffect = dynamic_cast<EffectInstance*>( otherKnob->getHolder() ); if (!otherEffect) { return; } std::stringstream expr; boost::shared_ptr<NodeCollection> thisCollection = isEffect->getNode()->getGroup(); NodeGroup* otherIsGroup = dynamic_cast<NodeGroup*>(otherEffect); if ( otherIsGroup == thisCollection.get() ) { expr << "thisGroup"; // make expression generic if possible } else { expr << otherEffect->getNode()->getFullyQualifiedName(); } expr << "." << otherKnob->getName() << ".get()"; if (otherKnob->getDimension() > 1) { expr << "[dimension]"; } thisKnob->beginChanges(); for (int i = 0; i < thisKnob->getDimension(); ++i) { if ( (i == dimension) || (dimension == -1) ) { thisKnob->setExpression(i, expr.str(), false, false); } } thisKnob->endChanges(); thisKnob->getHolder()->getApp()->triggerAutoSave(); } } } // KnobGui::linkTo
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
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
void PasteUndoCommand::copyFrom(const KnobPtr& serializedKnob, bool isRedo) { KnobPtr internalKnob = _imp->knob.lock()->getKnob(); switch (_imp->type) { case eKnobClipBoardTypeCopyAnim: { internalKnob->beginChanges(); for (int i = 0; i < internalKnob->getDimension(); ++i) { if ( ( _imp->targetDimension == -1) || ( i == _imp->targetDimension) ) { boost::shared_ptr<Curve> fromCurve; if ( ( i == _imp->targetDimension) && ( _imp->fromDimension != -1) ) { fromCurve = serializedKnob->getCurve(ViewIdx(0), _imp->fromDimension); } else { fromCurve = serializedKnob->getCurve(ViewIdx(0), i); } if (!fromCurve) { continue; } internalKnob->cloneCurve(ViewIdx(0), i, *fromCurve); } } internalKnob->endChanges(); break; } case eKnobClipBoardTypeCopyValue: { Knob<int>* isInt = dynamic_cast<Knob<int>*>( internalKnob.get() ); Knob<bool>* isBool = dynamic_cast<Knob<bool>*>( internalKnob.get() ); Knob<double>* isDouble = dynamic_cast<Knob<double>*>( internalKnob.get() ); Knob<std::string>* isString = dynamic_cast<Knob<std::string>*>( internalKnob.get() ); Knob<int>* isFromInt = dynamic_cast<Knob<int>*>( serializedKnob.get() ); Knob<bool>* isFromBool = dynamic_cast<Knob<bool>*>( serializedKnob.get() ); Knob<double>* isFromDouble = dynamic_cast<Knob<double>*>( serializedKnob.get() ); Knob<std::string>* isFromString = dynamic_cast<Knob<std::string>*>( serializedKnob.get() ); internalKnob->beginChanges(); for (int i = 0; i < internalKnob->getDimension(); ++i) { if ( ( _imp->targetDimension == -1) || ( i == _imp->targetDimension) ) { if (isInt && isFromInt) { int f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromInt->getValue(_imp->fromDimension) : isFromInt->getValue(i); isInt->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0); } else if (isBool && isFromBool) { bool f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromBool->getValue(_imp->fromDimension) : isFromBool->getValue(i); isBool->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0); } else if (isDouble && isFromDouble) { double f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromDouble->getValue(_imp->fromDimension) : isFromDouble->getValue(i); isDouble->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0); } else if (isString && isFromString) { std::string f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromString->getValue(_imp->fromDimension) : isFromString->getValue(i); isString->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0); } } } internalKnob->endChanges(); break; } case eKnobClipBoardTypeCopyLink: { //bool useExpression = !KnobI::areTypesCompatibleForSlave(internalKnob.get(), serializedKnob.get()); internalKnob->beginChanges(); for (int i = 0; i < internalKnob->getDimension(); ++i) { if ( ( _imp->targetDimension == -1) || ( i == _imp->targetDimension) ) { if (isRedo) { if (_imp->fromDimension != -1) { internalKnob->slaveTo(i, serializedKnob, _imp->fromDimension); } else { internalKnob->slaveTo(i, serializedKnob, i); } } else { internalKnob->unSlave(i, false); } } } internalKnob->endChanges(); break; } } // switch } // redo