void TKeyframeSelection::setKeyframes() { TApp *app = TApp::instance(); TXsheetHandle *xsheetHandle = app->getCurrentXsheet(); TXsheet *xsh = xsheetHandle->getXsheet(); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); if (isEmpty()) return; Position pos = *m_positions.begin(); int row = pos.first; int col = pos.second; TStageObjectId id = col < 0 ? cameraId : TStageObjectId::ColumnId(col); TStageObject *pegbar = xsh->getStageObject(id); if (!pegbar) return; if (pegbar->isKeyframe(row)) { TStageObject::Keyframe key = pegbar->getKeyframe(row); pegbar->removeKeyframeWithoutUndo(row); UndoRemoveKeyFrame *undo = new UndoRemoveKeyFrame(id, row, key, xsheetHandle); undo->setObjectHandle(app->getCurrentObject()); TUndoManager::manager()->add(undo); } else { pegbar->setKeyframeWithoutUndo(row); UndoSetKeyFrame *undo = new UndoSetKeyFrame(id, row, xsheetHandle); undo->setObjectHandle(app->getCurrentObject()); TUndoManager::manager()->add(undo); } TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance()->getCurrentObject()->notifyObjectIdChanged(false); }
void Stage::visit(Visitor &visitor, const VisitArgs &args) { ToonzScene *scene = args.m_scene; TXsheet *xsh = args.m_xsh; int row = args.m_row; int col = args.m_col; const OnionSkinMask *osm = args.m_osm; bool camera3d = args.m_camera3d; int xsheetLevel = args.m_xsheetLevel; bool isPlaying = args.m_isPlaying; StageBuilder sb; sb.m_vs = &visitor.m_vs; TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); TStageObject *camera = xsh->getStageObject(cameraId); TAffine cameraAff = camera->getPlacement(row); double z = camera->getZ(row); sb.m_cameraPlacement = ZPlacement(cameraAff, z); sb.m_camera3d = camera3d; sb.m_currentColumnIndex = col; sb.m_xsheetLevel = xsheetLevel; sb.m_onionSkinMask = *osm; Player::m_onionSkinFrontSize = 0; Player::m_onionSkinBackSize = 0; sb.addFrame(sb.m_players, scene, xsh, row, 0, args.m_onlyVisible, args.m_checkPreviewVisibility); updateOnionSkinSize(sb.m_players); sb.visit(sb.m_players, visitor, isPlaying); }
//----------------------------------------------------------------------------- // data <- xsheet void TKeyframeData::setKeyframes(std::set<Position> positions, TXsheet *xsh) { if (positions.empty()) return; TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); std::set<Position>::iterator it = positions.begin(); int r0 = it->first; int c0 = it->second; for (++it; it != positions.end(); ++it) { r0 = std::min(r0, it->first); c0 = std::min(c0, it->second); } for (it = positions.begin(); it != positions.end(); ++it) { int row = it->first; int col = it->second; TStageObject *pegbar = xsh->getStageObject(col >= 0 ? TStageObjectId::ColumnId(col) : cameraId); assert(pegbar); m_isPegbarsCycleEnabled[col] = pegbar->isCycleEnabled(); if (pegbar->isKeyframe(row)) { Position p(row - r0, col - c0); TStageObject::Keyframe k = pegbar->getKeyframe(row); m_keyData[p] = k; } } }
bool ViewerKeyframeNavigator::hasPrev() const { TStageObject *pegbar = getStageObject(); if (!pegbar) return false; int r0, r1; pegbar->getKeyframeRange(r0, r1); return r0 <= r1 && getCurrentFrame() > r0; }
bool ViewerKeyframeNavigator::hasKeyframes() const { TStageObject *pegbar = getStageObject(); if (!pegbar) return false; int r0, r1; pegbar->getKeyframeRange(r0, r1); return r0 <= r1; }
void TColumnDataElement::storeColumn(TXsheet *xsh, int index, int fxFlags) { if (index < 0) return; bool doClone = (fxFlags & eDoClone); bool resetFxDagPositions = (fxFlags & eResetFxDagPositions); // Fetch the specified column (if none, return) TStageObject *obj = xsh->getStageObject(TStageObjectId::ColumnId(index)); assert(obj); TXshColumn *column = xsh->getColumn(index); if (!column) return; TFx *fx = column->getFx(); TPointD dagPos; if (fx) dagPos = fx->getAttributes()->getDagNodePos(); if (doClone) column = column->clone(); // Zerary fxs clone the associated fx (drawn levels do not) if (fx && !resetFxDagPositions) column->getFx()->getAttributes()->setDagNodePos(dagPos); m_column = column; storeObject(obj->getId(), xsh); }
void SkeletonTool::magicLink(int index) { if (index < 0 || index >= (int)m_magicLinks.size()) return; HookData h0 = m_magicLinks[index].m_h0; HookData h1 = m_magicLinks[index].m_h1; TTool::Application *app = TTool::getApplication(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); int columnIndex = app->getCurrentColumn()->getColumnIndex(); TStageObjectId id = TStageObjectId::ColumnId(columnIndex); TStageObject *obj = xsh->getStageObject(id); int parentColumnIndex = h1.m_columnIndex; TStageObjectId parentId = TStageObjectId::ColumnId(parentColumnIndex); std::string parentHandle = h1.getHandle(); std::string handle = ""; if (h0.m_columnIndex < 0) { handle = obj->getHandle(); } else { handle = h0.getHandle(); } //TUndoManager *undoManager = TUndoManager::manager(); //undoManager->beginBlock(); TStageObjectCmd::setHandle(id, handle, app->getCurrentXsheet()); TStageObjectCmd::setParent(id, parentId, parentHandle, app->getCurrentXsheet()); //undoManager->endBlock(); }
bool ViewerKeyframeNavigator::isFullKeyframe() const { TStageObject *pegbar = getStageObject(); if (!pegbar) return false; return pegbar->isFullKeyframe(getCurrentFrame()); }
void addBoneId(const TStageObjectId &id) { TStageObject *stageObject = getXsheet()->getStageObject(id); if (stageObject) { TStageObject::Keyframe k = stageObject->getKeyframe(m_frame); m_keyframes.push_back(std::make_pair(id, k)); } }
void TApp::onSplineChanged() { if (m_currentObject->isSpline()) { TXsheet *xsh = m_currentXsheet->getXsheet(); TStageObject *currentObject = xsh->getStageObject(m_currentObject->getObjectId()); currentObject->setOffset(currentObject->getOffset()); //invalidate currentObject } }
void TStageObjectDataElement::storeObject(const TStageObjectId &objId, TXsheet *xsh) { // Search the object in the xsheet (false = don't create a new one) TStageObject *obj = xsh->getStageObjectTree()->getStageObject(objId, false); assert(obj); m_params = obj->getParams(); m_dagPos = obj->getDagNodePos(); }
void TCameraDataElement::storeCamera(const TStageObjectId &selectedObj, TXsheet *xsh) { TStageObject *obj = xsh->getStageObjectTree()->getStageObject(selectedObj, false); assert(obj); m_params = obj->getParams(); m_camera = *(obj->getCamera()); m_dagPos = obj->getDagNodePos(); }
void TCellKeyframeSelection::selectCellKeyframe(int row, int col) { m_cellSelection->selectCell(row, col); TXsheet *xsh = m_xsheetHandle->getXsheet(); TStageObjectId id = col < 0 ? TStageObjectId::CameraId(0) : TStageObjectId::ColumnId(col); TStageObject *stObj = xsh->getStageObject(id); m_keyframeSelection->clear(); if (stObj->isKeyframe(row)) m_keyframeSelection->select(row, col); }
void TApp::onObjectSwitched() { if (m_currentObject->isSpline()) { TXsheet *xsh = m_currentXsheet->getXsheet(); TStageObject *currentObject = xsh->getStageObject(m_currentObject->getObjectId()); TStageObjectSpline *ps = currentObject->getSpline(); m_currentObject->setSplineObject(ps); } else m_currentObject->setSplineObject(0); onImageChanged(); }
void StageBuilder::addFrame(PlayerSet &players, ToonzScene *scene, TXsheet *xsh, int row, int level, bool includeUnvisible, bool checkPreviewVisibility) { int columnCount = xsh->getColumnCount(); unsigned int maskCount = m_masks.size(); std::vector<std::pair<double, int>> shuffle; for (int c = 0; c < columnCount; c++) { TXshColumnP column = xsh->getColumn(c); assert(column); TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(c)); double columnSO = pegbar->getSO(row); shuffle.push_back(std::make_pair(columnSO, c)); } std::stable_sort(shuffle.begin(), shuffle.end(), StackingOrder()); for (int i = 0; i < columnCount; i++) { int c = shuffle[i].second; if (CameraTestCheck::instance()->isEnabled() && c != m_currentColumnIndex) continue; if (level == 0) { // m_isCurrentColumn = (c == m_currentColumnIndex); m_ancestorColumnIndex = c; } TXshColumn *column = xsh->getColumn(c); bool isMask = false; if (column && !column->isEmpty()) { if (!column->isPreviewVisible() && checkPreviewVisibility) continue; if (column->isCamstandVisible() || includeUnvisible) // se l'"occhietto" non e' chiuso { if (column->isMask()) // se e' una maschera (usate solo in tab pro) { isMask = true; std::vector<int> saveMasks; saveMasks.swap(m_masks); int maskIndex = m_maskPool.size(); PlayerSet *mask = new PlayerSet(); m_maskPool.push_back(mask); addCellWithOnionSkin(*mask, scene, xsh, row, c, level); std::stable_sort(mask->begin(), mask->end(), PlayerLt()); saveMasks.swap(m_masks); m_masks.push_back(maskIndex); } else addCellWithOnionSkin(players, scene, xsh, row, c, level); } } if (!isMask) { while (m_masks.size() > maskCount) m_masks.pop_back(); } } if (level == 0) std::stable_sort(players.begin(), players.end(), PlayerLt()); }
void ViewerKeyframeNavigator::goPrev() { TStageObject *pegbar = getStageObject(); if (!pegbar) return; int frame = getCurrentFrame(); TStageObject::KeyframeMap keyframes; pegbar->getKeyframes(keyframes); TStageObject::KeyframeMap::reverse_iterator it; for (it = keyframes.rbegin(); it != keyframes.rend(); ++it) if (it->first < frame) { setCurrentFrame(it->first); return; } }
static inline bool isMeshDeformed(TXsheet *xsh, TStageObject *obj, const ImagePainter::VisualSettings *vs) { const TStageObjectId &parentId = obj->getParent(); if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') { TStageObject *parentObj = xsh->getStageObject(parentId); if (!parentObj->getPlasticSkeletonDeformation()) return false; TXshColumn *parentCol = xsh->getColumn(parentId.getIndex()); return (parentCol->getColumnType() == TXshColumn::eMeshType) && (parentCol != vs->m_plasticVisualSettings.m_showOriginalColumn); } return false; }
void addShowHideStageObjectCmd(QMenu *menu, const TStageObjectId &id, bool isShow) { TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TStageObject *pegbar = xsh->getStageObject(id); QString cmdStr; if (id.isCamera()) cmdStr = (isShow ? "Show " : "Hide ") + QString::fromStdString(pegbar->getName()); else cmdStr = (isShow ? "Show Column" : "Hide Column") + QString::fromStdString(pegbar->getName()); QAction *showHideAction = new QAction(cmdStr, menu); showHideAction->setData((int)id.getCode()); menu->addAction(showHideAction); }
void TCellKeyframeSelection::selectCellsKeyframes(int r0, int c0, int r1, int c1) { m_cellSelection->selectCells(r0, c0, r1, c1); TXsheet *xsh = m_xsheetHandle->getXsheet(); m_xsheetHandle->getXsheet(); if (r1 < r0) std::swap(r0, r1); if (c1 < c0) std::swap(c0, c1); m_keyframeSelection->clear(); int r, c; for (c = c0; c <= c1; c++) for (r = r0; r <= r1; r++) { TStageObjectId id = c < 0 ? TStageObjectId::CameraId(0) : TStageObjectId::ColumnId(c); TStageObject *stObj = xsh->getStageObject(id); if (stObj->isKeyframe(r)) m_keyframeSelection->select(r, c); } }
void StageSchematicScene::updateScene() { clearAllItems(); QPointF firstPos = sceneRect().center(); m_nextNodePos = TPointD(firstPos.x(), firstPos.y()); TStageObjectTree *pegTree = m_xshHandle->getXsheet()->getStageObjectTree(); m_nodeTable.clear(); m_GroupTable.clear(); m_groupEditorTable.clear(); m_gridDimension = pegTree->getDagGridDimension(); QMap<int, QList<TStageObject *>> groupedObj; QMap<int, QList<SchematicNode *>> editedGroup; // in order to draw the position-specified nodes first QList<int> modifiedNodeIds; for (int i = 0; i < pegTree->getStageObjectCount(); i++) { TStageObject *pegbar = pegTree->getStageObject(i); if (pegbar->getDagNodePos() == TConst::nowhere) modifiedNodeIds.push_back(i); else modifiedNodeIds.push_front(i); } for (int i = 0; i < modifiedNodeIds.size(); i++) { TStageObject *pegbar = pegTree->getStageObject(modifiedNodeIds.at(i)); if (pegbar->isGrouped() && !pegbar->isGroupEditing()) { groupedObj[pegbar->getGroupId()].push_back(pegbar); continue; } StageSchematicNode *node = addStageSchematicNode(pegbar); if (node != 0) { m_nodeTable[pegbar->getId()] = node; if (pegbar->isGrouped()) editedGroup[pegbar->getEditingGroupId()].append(node); } } //Motion Path m_splineTable.clear(); for (int i = 0; i < pegTree->getSplineCount(); i++) { TStageObjectSpline *spline = pegTree->getSpline(i); StageSchematicSplineNode *node = addSchematicSplineNode(spline); if (node != 0) { m_splineTable[spline] = node; connect(node, SIGNAL(currentObjectChanged(const TStageObjectId &, bool)), this, SLOT(onCurrentObjectChanged(const TStageObjectId &, bool))); } }
TStageObjectId TColumnDataElement::restoreColumn(TXsheet *xsh, int index, int fxFlags, bool copyPosition) const { bool doClone = (fxFlags & eDoClone); bool resetFxDagPositions = (fxFlags & eResetFxDagPositions); TXshColumn *column = m_column.getPointer(); // The xsheet 'changes' if a new column is inserted. If it was already there, no. bool xsheetChange = false; if (column && column->getXsheet() && column->getXsheet() != xsh) xsheetChange = true; // Insert a column at the specified index. If a column was stored, insert that one. TPointD dagPos = TConst::nowhere; if (column) { if (column->getFx()) dagPos = column->getFx()->getAttributes()->getDagNodePos(); if (doClone) column = column->clone(); xsh->insertColumn(index, column); } else xsh->insertColumn(index); // Create a new one otherwise if (!resetFxDagPositions && dagPos != TConst::nowhere) { // Don't accept the default position (fx object) TXshColumn *restoredColumn = xsh->getColumn(index); restoredColumn->getFx()->getAttributes()->setDagNodePos(dagPos); } // Retrieve the newly inserted column stage object TStageObject *obj = xsh->getStageObject(TStageObjectId::ColumnId(index)); assert(obj); obj->assignParams(m_params, doClone); // Assign the stored params if (copyPosition) obj->setDagNodePos(m_dagPos); // Clone the associated curve if any if (xsheetChange && obj->getSpline()) { TStageObjectSpline *srcSpl = obj->getSpline(); TStageObjectSpline *dstSpl = xsh->getStageObjectTree()->createSpline(); dstSpl->addRef(); dstSpl->setStroke(new TStroke(*srcSpl->getStroke())); obj->setSpline(dstSpl); } int gridType = xsh->getStageObjectTree()->getDagGridDimension(); obj->setIsOpened(gridType == 0); // gridType is 0 if the node is opened, 1 if closed // see StageSchematicScene::GridDimension // TODO: Should be made PUBLIC!! xsh->updateFrameCount(); return obj->getId(); }
TStageObjectId TCameraDataElement::restoreCamera(TXsheet *xsh, bool copyPosition) const { TStageObjectTree *tree = xsh->getStageObjectTree(); // Search the first unused camera id in the xsheet int index = 0; while (tree->getStageObject(TStageObjectId::CameraId(index), false)) ++index; // Create the new camera object and assign stored data TStageObject *newCamera = tree->getStageObject(TStageObjectId::CameraId(index), true); newCamera->assignParams(m_params); *(newCamera->getCamera()) = m_camera; if (copyPosition) newCamera->setDagNodePos(m_dagPos); return newCamera->getId(); }
void redo() const { TXsheet *xsh = getXsheet(); for (int i = 0; i < (int)m_keyframes.size(); i++) { TStageObject *stageObject = getXsheet()->getStageObject(m_keyframes[i].first); if (stageObject) stageObject->setKeyframeWithoutUndo(m_frame); } m_tool->setTemporaryPinnedColumns(m_newTemp); if (m_oldColumnIndex >= 0) getRangeSet(m_oldColumnIndex)->removeRange(m_oldRange.first, m_oldRange.second); if (m_columnIndex >= 0) { TPinnedRangeSet *rangeSet = getRangeSet(m_columnIndex); rangeSet->setRange(m_newRange.first, m_newRange.second); rangeSet->setPlacement(m_newPlacement); } notify(); }
TStageObjectId TStageObjectDataElement::restoreObject(TXsheet *xsh, bool copyPosition) const { int index = 2; // Skip the table and camera 1 (I guess) // Search the first unused common (pegbar) id TStageObjectTree *tree = xsh->getStageObjectTree(); while (tree->getStageObject(TStageObjectId::PegbarId(index), false)) ++index; // Create the new object to be inserted TStageObject *newObj = tree->getStageObject(TStageObjectId::PegbarId(index), true); newObj->setParent(m_params->m_parentId); newObj->assignParams(m_params); // If specified, copy the stored position in the viewer if (copyPosition) newObj->setDagNodePos(m_dagPos); return newObj->getId(); }
/*! Notify change of current image: update icon and notify level change. If current object is a spline commit spline chenged. If current mode is EditingLevel touch current frame. */ void TTool::notifyImageChanged() { onImageChanged(); if (!m_application) return; m_application->getCurrentScene()->setDirtyFlag(true); if (m_application->getCurrentFrame()->isEditingLevel()) { TXshLevel *xl = m_application->getCurrentLevel()->getLevel(); if (!xl) return; TXshSimpleLevel *sl = xl->getSimpleLevel(); if (!sl) return; TFrameId fid = m_application->getCurrentFrame()->getFid(); sl->touchFrame(fid); // sl->setDirtyFlag(true); IconGenerator::instance()->invalidate(sl, fid); IconGenerator::instance()->invalidateSceneIcon(); } else { TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); if (!xsh) return; TObjectHandle *currentObject = m_application->getCurrentObject(); if (currentObject->isSpline()) { m_application->getCurrentObject()->commitSplineChanges(); TStageObject *pegbar = xsh->getStageObject(currentObject->getObjectId()); IconGenerator::instance()->invalidate(pegbar->getSpline()); } else { int row = m_application->getCurrentFrame()->getFrame(); int col = m_application->getCurrentColumn()->getColumnIndex(); if (col < 0) return; TXshCell cell = xsh->getCell(row, col); TXshSimpleLevel *sl = cell.getSimpleLevel(); if (sl) { IconGenerator::instance()->invalidate(sl, cell.m_frameId); sl->touchFrame(cell.m_frameId); IconGenerator::instance()->invalidateSceneIcon(); } } } m_application->getCurrentLevel()->notifyLevelChange(); }
bool addFrame(ToonzScene &scene, int row, bool isLast) { TAffine cameraView = scene.getXsheet()->getPlacement(TStageObjectId::CameraId(0), row).inv(); TPixel32 bgColor = scene.getProperties()->getBgColor(); TStageObject *cameraPegbar = scene.getXsheet()->getStageObject(TStageObjectId::CameraId(0)); assert(cameraPegbar); TCamera *camera = cameraPegbar->getCamera(); assert(camera); TAffine dpiAff = getDpiAffine(camera).inv(); TAffine aff = cameraView * dpiAff; Stage::VisitArgs args; args.m_scene = &scene; args.m_xsh = scene.getXsheet(); args.m_row = row; args.m_col = m_columnIndex; args.m_osm = &m_osMask; ImagePainter::VisualSettings vs; FlashStagePainter painter(m_flash, aff, vs, bgColor); m_flash.beginFrame(++m_frameIndex); Stage::visit(painter, args); /* &scene, scene.getXsheet(), row, m_columnIndex, m_osMask, false, 0); */ m_frameIndex = m_flash.endFrame(isLast, m_frameCountLoader, (m_sceneCount == m_sceneIndex)); return true; }
// data -> xsh bool TKeyframeData::getKeyframes(std::set<Position> &positions, TXsheet *xsh) const { std::set<TKeyframeSelection::Position>::iterator it2 = positions.begin(); int r0 = it2->first; int c0 = it2->second; for (++it2; it2 != positions.end(); ++it2) { r0 = std::min(r0, it2->first); c0 = std::min(c0, it2->second); } positions.clear(); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); Iterator it; bool keyFrameChanged = false; for (it = m_keyData.begin(); it != m_keyData.end(); ++it) { Position pos = it->first; int row = r0 + pos.first; int col = c0 + pos.second; positions.insert(std::make_pair(row, col)); TXshColumn *column = xsh->getColumn(col); if (column && column->getSoundColumn()) continue; TStageObject *pegbar = xsh->getStageObject(col >= 0 ? TStageObjectId::ColumnId(col) : cameraId); if (pegbar->getId().isColumn() && xsh->getColumn(col) && xsh->getColumn(col)->isLocked()) continue; keyFrameChanged = true; assert(pegbar); pegbar->setKeyframeWithoutUndo(row, it->second); } if (!keyFrameChanged) return false; for (auto const pegbar : m_isPegbarsCycleEnabled) { int const col = pegbar.first; TStageObjectId objectId = (col >= 0) ? TStageObjectId::ColumnId(col) : cameraId; xsh->getStageObject(objectId)->enableCycle(pegbar.second); } return true; }
TAffine TTool::getCurrentObjectParentMatrix2() const { TTool::Application *app = m_application; TFrameHandle *fh = app->getCurrentFrame(); if (fh->isEditingLevel()) return TAffine(); int frame = fh->getFrame(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TStageObjectId id = app->getCurrentObject()->getObjectId(); double objZ = xsh->getZ(id, frame); TStageObjectId parentId = xsh->getStageObjectParent(id); if (parentId == TStageObjectId::NoneId) return TAffine(); id = parentId; TAffine objPlacement = xsh->getPlacement(id, frame); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); TStageObject *camera = xsh->getStageObject(cameraId); TAffine cameraPlacement = camera->getPlacement(frame); double cameraZ = camera->getZ(frame); TAffine placement; TStageObject::perspective(placement, cameraPlacement, cameraZ, objPlacement, objZ, 0); return placement; }
TAffine TTool::getColumnMatrix(int columnIndex) const { if (!m_application) return TAffine(); TFrameHandle *fh = m_application->getCurrentFrame(); if (fh->isEditingLevel()) return TAffine(); int frame = fh->getFrame(); TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet(); TStageObjectId columnId = TStageObjectId::ColumnId(columnIndex); TAffine columnPlacement = xsh->getPlacement(columnId, frame); double columnZ = xsh->getZ(columnId, frame); TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); TStageObject *camera = xsh->getStageObject(cameraId); TAffine cameraPlacement = camera->getPlacement(frame); double cameraZ = camera->getZ(frame); TStageObject *object = xsh->getStageObject(columnId); TAffine placement; TStageObject::perspective(placement, cameraPlacement, cameraZ, columnPlacement, columnZ, object->getGlobalNoScaleZ()); return placement; }
void ViewerKeyframeNavigator::toggle() { TStageObject *pegbar = getStageObject(); if (!pegbar) return; int frame = getCurrentFrame(); if (pegbar->isFullKeyframe(frame)) { TStageObject::Keyframe key = pegbar->getKeyframe(frame); pegbar->removeKeyframeWithoutUndo(frame); UndoRemoveKeyFrame *undo = new UndoRemoveKeyFrame(pegbar->getId(), frame, key, m_xsheetHandle); undo->setObjectHandle(m_objectHandle); TUndoManager::manager()->add(undo); } else { UndoSetKeyFrame *undo = new UndoSetKeyFrame(pegbar->getId(), frame, m_xsheetHandle); pegbar->setKeyframeWithoutUndo(frame); undo->setObjectHandle(m_objectHandle); TUndoManager::manager()->add(undo); } m_objectHandle->notifyObjectIdChanged(false); }