void DSPasteKeysCommand::addOrRemoveKeyframe(bool add) { for (std::list<boost::weak_ptr<DSKnob> >::const_iterator it = _dstKnobs.begin(); it != _dstKnobs.end(); ++it) { DSKnobPtr knobContext = it->lock(); if (!knobContext) { continue; } for (std::size_t i = 0; i < _keys.size(); ++i) { int dim = knobContext->getDimension(); KnobIPtr knob = knobContext->getInternalKnob(); knob->beginChanges(); double keyTime = _keys[i].key.getTime(); double setTime = _pasteRelativeToRefTime ? keyTime - _keys[_refKeyindex].key.getTime() + _refTime : keyTime; if (add) { for (int j = 0; j < knob->getDimension(); ++j) { if ( (dim == -1) || (j == dim) ) { KeyFrame k = _keys[i].key; k.setTime(setTime); knob->setKeyFrame(k, ViewSpec::all(), j, eValueChangedReasonNatronGuiEdited); } } } else { for (int j = 0; j < knob->getDimension(); ++j) { if ( (dim == -1) || (j == dim) ) { knob->deleteValueAtTime(eCurveChangeReasonDopeSheet, setTime, ViewSpec::all(), j, i == 0); } } } knob->endChanges(); } } _model->refreshSelectionBboxAndRedrawView(); } // DSPasteKeysCommand::addOrRemoveKeyframe
void SetExpressionCommand::undo() { KnobIPtr knob = _knob.lock(); if (!knob) { return; } knob->beginChanges(); try { int nDims = knob->getNDimensions(); std::list<ViewIdx> allViews = knob->getViewsList(); if (_dimension.isAll()) { for (int i = 0; i < nDims; ++i) { if (_view.isAll()) { for (std::list<ViewIdx>::const_iterator it = allViews.begin(); it!=allViews.end(); ++it) { setOldExprForDimView(knob, DimIdx(i), *it, _oldExprs); } } else { setOldExprForDimView(knob, DimIdx(i), ViewIdx(_view), _oldExprs); } } } else { if (_view.isAll()) { for (std::list<ViewIdx>::const_iterator it = allViews.begin(); it!=allViews.end(); ++it) { setOldExprForDimView(knob, DimIdx(_dimension), *it, _oldExprs); } } else { setOldExprForDimView(knob, DimIdx(_dimension), ViewIdx(_view), _oldExprs); } } } catch (...) { Dialogs::errorDialog( tr("Expression").toStdString(), tr("The expression is invalid.").toStdString() ); } knob->endChanges(); }
void PasteKnobClipBoardUndoCommand::copyFrom(const SERIALIZATION_NAMESPACE::KnobSerializationPtr& serializedKnob, const KnobIPtr& fromKnob, bool isRedo) { KnobIPtr internalKnob = _imp->knob.lock(); if (!internalKnob) { return; } // Get the target type KnobIntBasePtr isInt = toKnobIntBase( internalKnob ); KnobBoolBasePtr isBool = toKnobBoolBase( internalKnob ); KnobDoubleBasePtr isDouble = toKnobDoubleBase( internalKnob ); KnobStringBasePtr isString = toKnobStringBase( internalKnob ); // Get view names std::vector<std::string> projectViewNames; if (internalKnob->getHolder() && internalKnob->getHolder()->getApp()) { projectViewNames = internalKnob->getHolder()->getApp()->getProject()->getProjectViewNames(); } // group changes under the same evaluation internalKnob->beginChanges(); std::list<ViewIdx> targetKnobViews = internalKnob->getViewsList(); StringAnimationManagerPtr fromAnimString; if (fromKnob) { fromAnimString = fromKnob->getStringAnimation(); } for (std::list<ViewIdx>::const_iterator it = targetKnobViews.begin(); it != targetKnobViews.end(); ++it) { if ( ( !_imp->targetView.isAll()) && ( *it != _imp->targetView) ) { continue; } // If dimensions are folded, expand them when linking if (_imp->targetDimension.isAll() && !internalKnob->getAllDimensionsVisible(*it)) { internalKnob->setAllDimensionsVisible(*it, true); } for (int i = 0; i < internalKnob->getNDimensions(); ++i) { if ( ( !_imp->targetDimension.isAll()) && ( i != _imp->targetDimension) ) { continue; } ViewIdx fromView; DimIdx fromDim; if ( !_imp->targetDimension.all() && !_imp->fromDimension.isAll() ) { fromDim = DimIdx(_imp->fromDimension); } else { // If the source knob dimension is all or target dimension is all copy dimension to dimension respectively fromDim = DimIdx(i); } if ( !_imp->targetView.isAll() && !_imp->fromView.isAll() ) { fromView = ViewIdx(_imp->fromView); } else { // If the source knob view is all or target view is all copy view to view respectively fromView = *it; } switch (_imp->type) { case eKnobClipBoardTypeCopyAnim: { std::string fromViewName; if (fromView >= 0 && fromView < (int)projectViewNames.size()) { fromViewName = projectViewNames[_imp->fromView]; } else { fromViewName = "Main"; } SERIALIZATION_NAMESPACE::KnobSerialization::PerViewValueSerializationMap::const_iterator foundFromView = serializedKnob->_values.find(fromViewName); if (foundFromView == serializedKnob->_values.end()) { continue; } if (fromDim < 0 || fromDim >= (int) foundFromView->second.size()) { continue; } // Read the curve from the clipboard CurvePtr fromCurve(new Curve()); if (!foundFromView->second[_imp->fromDimension]._animationCurve.keys.empty()) { fromCurve->fromSerialization(foundFromView->second[_imp->fromDimension]._animationCurve); } internalKnob->cloneCurve(*it, DimIdx(i), *fromCurve, 0 /*offset*/, 0 /*range*/, fromAnimString.get()); break; } case eKnobClipBoardTypeCopyValue: { std::string fromViewName; if (fromView >= 0 && fromView < (int)projectViewNames.size()) { fromViewName = projectViewNames[_imp->fromView]; } else { fromViewName = "Main"; } SERIALIZATION_NAMESPACE::KnobSerialization::PerViewValueSerializationMap::const_iterator foundFromView = serializedKnob->_values.find(fromViewName); if (foundFromView == serializedKnob->_values.end()) { continue; } if (fromDim < 0 || fromDim >= (int) foundFromView->second.size()) { continue; } internalKnob->restoreValueFromSerialization(foundFromView->second[fromDim], DimIdx(i), *it); break; } case eKnobClipBoardTypeCopyLink: { if (isRedo) { internalKnob->slaveTo(fromKnob, DimIdx(i), fromDim, *it, fromView); } else { internalKnob->unSlave(DimIdx(i), *it, false /*copyState*/); } break; } case eKnobClipBoardTypeCopyExpressionLink: case eKnobClipBoardTypeCopyExpressionMultCurveLink: { if (isRedo) { std::string expression = makeLinkExpression(projectViewNames, internalKnob, _imp->type == eKnobClipBoardTypeCopyExpressionMultCurveLink, fromKnob, _imp->fromDimension, _imp->fromView, _imp->targetDimension, _imp->targetView); const bool hasRetVar = false; try { // Don't fail if exception is invalid, it should have been tested prior to creating an undo/redo command, otherwise user is going // to hit CTRL-Z and nothing will happen internalKnob->setExpression(DimIdx(i), *it, expression, hasRetVar, /*failIfInvalid*/ false); } catch (...) { } } else { // !isRedo internalKnob->clearExpression(DimIdx(i), *it, true); } // isRedo break; } }; // switch } // for all dimensions } // for all views internalKnob->endChanges(); } // redo