diff --git a/toonz/sources/toonz/columncommand.cpp b/toonz/sources/toonz/columncommand.cpp index 372af70..ad06f47 100644 --- a/toonz/sources/toonz/columncommand.cpp +++ b/toonz/sources/toonz/columncommand.cpp @@ -43,6 +43,8 @@ // TnzBase includes #include "tfx.h" #include "tfxattributes.h" +#include "tparamcontainer.h" +#include "tparamset.h" // TnzCore includes #include "tstroke.h" @@ -98,9 +100,24 @@ void getColumnLinkedFxs(TFx *startFx, TFx *newStartFx, } } +//------------------------------------------------------ + +template +void setGrammerToParams(const ParamCont *cont, + const TSyntax::Grammar *grammer) { + for (int p = 0; p != cont->getParamCount(); ++p) { + TParam ¶m = *cont->getParam(p); + if (TDoubleParam *dp = dynamic_cast(¶m)) + dp->setGrammar(grammer); + else if (TParamSet *paramSet = dynamic_cast(¶m)) + setGrammerToParams(paramSet, grammer); + } +} + //----------------------------------------------------------------------------- -void cloneNotColumnLinkedFxsAndOutputsFx(TXsheet *xsh, TXsheet *newXsh) { +void cloneNotColumnLinkedFxsAndOutputsFx( + TXsheet *xsh, TXsheet *newXsh, QMap *fxTable = nullptr) { int columnCount = xsh->getColumnCount(); assert(newXsh->getColumnCount() == columnCount); @@ -134,6 +151,9 @@ void cloneNotColumnLinkedFxsAndOutputsFx(TXsheet *xsh, TXsheet *newXsh) { newFxDag->getInternalFxs()->addFx(newFx); if (fxDag->getTerminalFxs()->containsFx(fx)) newFxDag->getTerminalFxs()->addFx(newFx); + // if the fx has not unique name then let assignUniqueId() set the default + // name + if (newFx->getName() == newFx->getFxId()) newFx->setName(L""); newFxDag->assignUniqueId(newFx); clonedFxs[fx] = newFx; notColumnLinkedClonedFxs.append(newFx); @@ -201,6 +221,17 @@ void cloneNotColumnLinkedFxsAndOutputsFx(TXsheet *xsh, TXsheet *newXsh) { newOutputFx->getInputPort(0)->setFx(newInputFx); } } + + // reset grammers for all parameters of cloned fxs + // or they fails to refer to other parameters via expression + TSyntax::Grammar *grammer = newXsh->getStageObjectTree()->getGrammar(); + QMap::const_iterator it; + for (it = clonedFxs.constBegin(); it != clonedFxs.constEnd(); ++it) { + setGrammerToParams(it.value()->getParams(), grammer); + + // register to the fx table for expression management + if (fxTable) fxTable->insert(it.key(), it.value()); + } } //----------------------------------------------------------------------------- @@ -1075,11 +1106,13 @@ void ColumnCmd::cloneChild(int index) { data->storeColumns(indices, childXsh, 0); data->storeColumnFxs(indices, childXsh, 0); std::list restoredSplineIds; + QMap idTable; + QMap fxTable; data->restoreObjects(indices, restoredSplineIds, newChildXsh, - StageObjectsData::eDoClone); + StageObjectsData::eDoClone, idTable, fxTable); delete data; - cloneNotColumnLinkedFxsAndOutputsFx(childXsh, newChildXsh); + cloneNotColumnLinkedFxsAndOutputsFx(childXsh, newChildXsh, &fxTable); cloneXsheetTStageObjectTree(childXsh, newChildXsh); /*--以下は、Clone SubXsheet するときに、SubXsheet内にある子SubXsheetをクローンする関数 @@ -1092,6 +1125,10 @@ void ColumnCmd::cloneChild(int index) { newChildXsh->getFxDag()->getXsheetFx()->getAttributes()->setDagNodePos( childXsh->getFxDag()->getXsheetFx()->getAttributes()->getDagNodePos()); + ExpressionReferenceManager::instance()->refreshXsheetRefInfo(newChildXsh); + ExpressionReferenceManager::instance()->transferReference( + childXsh, newChildXsh, idTable, fxTable); + newChildXsh->updateFrameCount(); /*-- TXshChildLevel作成時にsetCellした1つ目のセルを消去 --*/ diff --git a/toonz/sources/toonz/expressionreferencemanager.cpp b/toonz/sources/toonz/expressionreferencemanager.cpp index a43aed3..6cc3d39 100644 --- a/toonz/sources/toonz/expressionreferencemanager.cpp +++ b/toonz/sources/toonz/expressionreferencemanager.cpp @@ -310,6 +310,21 @@ void ExpressionReferenceManager::onSceneSwitched() { //----------------------------------------------------------------------------- +void ExpressionReferenceManager::refreshXsheetRefInfo(TXsheet* xsh) { + xsh->setObserver(this); + m_model->refreshData(xsh); + xsh->getExpRefMonitor()->clearAll(); + for (int i = 0; i < m_model->getStageObjectsChannelCount(); i++) { + checkRef(m_model->getStageObjectChannel(i), xsh); + } + for (int i = 0; i < m_model->getFxsChannelCount(); i++) { + checkRef(m_model->getFxChannel(i), xsh); + } + onXsheetSwitched(); +} + +//----------------------------------------------------------------------------- + void ExpressionReferenceManager::onXsheetSwitched() { TXsheet* xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); xsh->setObserver(this); @@ -772,7 +787,8 @@ void ExpressionReferenceManager::transferReference( // 1. create 3 tables for replacing; column indices, parameter pointers, and // expression texts. Note that moving columns in the same xsheet does not need - // to replace the parameter pointers since they are swapped along with columns. + // to replace the parameter pointers since they are swapped along with + // columns. QMap colIdReplaceTable; QMap curveReplaceTable; std::map exprReplaceTable; diff --git a/toonz/sources/toonz/expressionreferencemanager.h b/toonz/sources/toonz/expressionreferencemanager.h index 4f04924..a6a8953 100644 --- a/toonz/sources/toonz/expressionreferencemanager.h +++ b/toonz/sources/toonz/expressionreferencemanager.h @@ -79,6 +79,7 @@ public: bool askIfParamIsIgnoredOnSave(bool saveSubXsheet); + void refreshXsheetRefInfo(TXsheet* xsh); protected slots: void onSceneSwitched(); void onXsheetSwitched(); diff --git a/toonz/sources/toonz/subscenecommand.cpp b/toonz/sources/toonz/subscenecommand.cpp index 2726d89..107faca 100644 --- a/toonz/sources/toonz/subscenecommand.cpp +++ b/toonz/sources/toonz/subscenecommand.cpp @@ -1300,7 +1300,7 @@ void collapseColumns(std::set indices, bool columnsOnly) { data->storeColumns(indices, xsh, StageObjectsData::eDoClone); data->storeColumnFxs(indices, xsh, StageObjectsData::eDoClone); - ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone(); + // ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone(); ToonzScene *scene = app->getCurrentScene()->getScene(); TXshLevel *xl = scene->createNewLevel(CHILD_XSHLEVEL); @@ -1323,6 +1323,7 @@ void collapseColumns(std::set indices, bool columnsOnly) { if (!columnsOnly) bringPegbarsInsideChildXsheet(xsh, childXsh, indices, newIndices, idTable); + ExpressionReferenceManager::instance()->refreshXsheetRefInfo(childXsh); ExpressionReferenceManager::instance()->transferReference(xsh, childXsh, idTable, fxTable); @@ -1411,7 +1412,7 @@ void collapseColumns(std::set indices, StageObjectsData::eDoClone); data->storeColumnFxs(indices, xsh, StageObjectsData::eDoClone); - ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone(); + // ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone(); ToonzScene *scene = app->getCurrentScene()->getScene(); TXshLevel *xl = scene->createNewLevel(CHILD_XSHLEVEL); @@ -1430,6 +1431,7 @@ void collapseColumns(std::set indices, fxTable); childXsh->updateFrameCount(); + ExpressionReferenceManager::instance()->refreshXsheetRefInfo(childXsh); ExpressionReferenceManager::instance()->transferReference(xsh, childXsh, idTable, fxTable); @@ -1475,7 +1477,7 @@ void collapseColumns(std::set indices, const std::set &fxs, data->storeColumns(indices, xsh, StageObjectsData::eDoClone); data->storeFxs(fxs, xsh, StageObjectsData::eDoClone); - ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone(); + // ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone(); ToonzScene *scene = app->getCurrentScene()->getScene(); TXshLevel *xl = scene->createNewLevel(CHILD_XSHLEVEL); @@ -1494,6 +1496,7 @@ void collapseColumns(std::set indices, const std::set &fxs, if (!columnsOnly) bringPegbarsInsideChildXsheet(xsh, childXsh, indices, newIndices, idTable); + ExpressionReferenceManager::instance()->refreshXsheetRefInfo(childXsh); ExpressionReferenceManager::instance()->transferReference(xsh, childXsh, idTable, fxTable); diff --git a/toonz/sources/toonzlib/fxcommand.cpp b/toonz/sources/toonzlib/fxcommand.cpp index ac3e1aa..e661775 100644 --- a/toonz/sources/toonzlib/fxcommand.cpp +++ b/toonz/sources/toonzlib/fxcommand.cpp @@ -129,6 +129,9 @@ inline void setFxParamToCurrentScene(TFx *fx, TXsheet *xsh) { void initializeFx(TXsheet *xsh, TFx *fx) { if (TZeraryColumnFx *zcfx = dynamic_cast(fx)) fx = zcfx->getZeraryFx(); + // if the fx has not unique name then let assignUniqueId() set the default + // name + if (fx->getName() != L"" && fx->getName() == fx->getFxId()) fx->setName(L""); xsh->getFxDag()->assignUniqueId(fx); setFxParamToCurrentScene(fx, xsh); diff --git a/toonz/sources/toonzqt/stageobjectsdata.cpp b/toonz/sources/toonzqt/stageobjectsdata.cpp index 5b83a5f..dc94d06 100644 --- a/toonz/sources/toonzqt/stageobjectsdata.cpp +++ b/toonz/sources/toonzqt/stageobjectsdata.cpp @@ -989,10 +989,20 @@ std::vector StageObjectsData::restoreObjects( dynamic_cast(pastedColumn)) { TZeraryColumnFx *zfx = zc->getZeraryColumnFx(); TFx *zeraryFx = zfx->getZeraryFx(); - if (zeraryFx && doClone) { - std::wstring app = zeraryFx->getName(); - fxDag->assignUniqueId(zeraryFx); - zeraryFx->setName(app); + if (zeraryFx) { + if (doClone) { + // if the fx has not unique name then let assignUniqueId() set the + // default name + if (zeraryFx->getName() == zeraryFx->getFxId()) + zeraryFx->setName(L""); + fxDag->assignUniqueId(zeraryFx); + } else + fxDag->updateFxIdTable(zeraryFx); + if (TXshZeraryFxColumn *orig_zc = + dynamic_cast(column)) { + if (TFx *origZeraryFx = orig_zc->getZeraryColumnFx()->getZeraryFx()) + fxTable[origZeraryFx] = zeraryFx; + } } } } @@ -1037,8 +1047,9 @@ std::vector StageObjectsData::restoreObjects( if (doClone) { fx = fxOrig->clone(false); - - fx->setName(fxOrig->getName()); + // if the fx has not unique name then let assignUniqueId() set the default + // name + if (fx->getName() == fx->getFxId()) fx->setName(L""); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; @@ -1083,7 +1094,10 @@ std::vector StageObjectsData::restoreObjects( linkedFx = fx->clone(false); linkedFx->linkParams(fx); - linkedFx->setName(oldLinkedFx->getName()); + // if the fx has not unique name then let assignUniqueId() set the + // default name + if (linkedFx->getName() == linkedFx->getFxId()) + linkedFx->setName(L""); linkedFx->getAttributes()->setId( oldLinkedFx->getAttributes()->getId()); linkedFx->getAttributes()->passiveCacheDataIdx() = -1;