bool removeKeyframes(KisImageSP image, const FrameItemList &frames) { bool result = false; QScopedPointer<KUndo2Command> cmd( new KUndo2Command(kundo2_i18np("Remove Keyframe", "Remove Keyframes", frames.size()))); // lisp-lovers present ;) foreach (const FrameItem &item, frames) { const int time = item.time; KisNodeSP node = item.node; KisKeyframeChannel *content = node->getKeyframeChannel(KisKeyframeChannel::Content.id()); if (!content) continue; KisKeyframeSP keyframe = content->keyframeAt(time); if (!keyframe) continue; content->deleteKeyframe(keyframe, cmd.data()); result = true; } if (result) { image->postExecutionUndoAdapter()->addCommand(toQShared(cmd.take())); } return result; }
KisKeyframeSP KisRasterKeyframeChannel::loadKeyframe(const QDomElement &keyframeNode) { int time = keyframeNode.attribute("time").toUInt(); QPoint offset; KisDomUtils::loadValue(keyframeNode, "offset", &offset); QString frameFilename = keyframeNode.attribute("frame"); KisKeyframeSP keyframe; if (m_d->frameFilenames.isEmpty()) { // First keyframe loaded: use the existing frame Q_ASSERT(keyframeCount() == 1); keyframe = constKeys().begin().value(); // Remove from keys. It will get reinserted with new time once we return keys().remove(keyframe->time()); keyframe->setTime(time); m_d->paintDevice->move(offset); } else { KUndo2Command tempCommand; int frameId = m_d->paintDevice->framesInterface()->createFrame(false, 0, offset, &tempCommand); keyframe = toQShared(new KisKeyframe(this, time, frameId)); } setFrameFilename(keyframe->value(), frameFilename); return keyframe; }
void KisAnimationCurvesModel::endCommand() { KIS_ASSERT_RECOVER_RETURN(m_d->undoCommand); image()->postExecutionUndoAdapter()->addCommand(toQShared(m_d->undoCommand)); m_d->undoCommand = 0; }
void KisMacroBasedUndoStore::addCommand(KUndo2Command *cmd) { /** * This store if stacked with a post-execution undo adapter, * so we should call redo() explicitly when adding a command. */ cmd->redo(); m_d->command->addCommand(toQShared(cmd)); }
KisKeyframeSP KisScalarKeyframeChannel::createKeyframe(int time, const KisKeyframeSP copySrc, KUndo2Command *parentCommand) { qreal value = (copySrc != 0) ? scalarValue(copySrc) : 0; int index = m_d->firstFreeIndex++; KUndo2Command *cmd = new Private::InsertValueCommand(m_d.data(), index, value, true, parentCommand); cmd->redo(); return toQShared(new KisKeyframe(this, time, index)); }
bool moveKeyframes(KisImageSP image, const FrameItemList &srcFrames, const FrameItemList &dstFrames, bool copy) { if (srcFrames.size() != dstFrames.size()) return false; bool result = false; QScopedPointer<KUndo2Command> cmd( new KUndo2Command(!copy ? kundo2_i18np("Move Keyframe", "Move Keyframes", srcFrames.size()) : kundo2_i18np("Copy Keyframe", "Copy Keyframes", srcFrames.size()))); // lisp-lovers present ;) for (int i = 0; i < srcFrames.size(); i++) { const int srcTime = srcFrames[i].time; KisNodeSP srcNode = srcFrames[i].node; const int dstTime = dstFrames[i].time; KisNodeSP dstNode = dstFrames[i].node; if (srcNode != dstNode) continue; KisKeyframeChannel *content = srcNode->getKeyframeChannel(KisKeyframeChannel::Content.id()); if (!content) continue; KisKeyframeSP dstKeyframe = content->keyframeAt(dstTime); if (dstKeyframe) { content->deleteKeyframe(dstKeyframe, cmd.data()); } KisKeyframeSP srcKeyframe = content->keyframeAt(srcTime); if (srcKeyframe) { if (copy) { content->copyKeyframe(srcKeyframe, dstTime, cmd.data()); } else { content->moveKeyframe(srcKeyframe, dstTime, cmd.data()); } } result = true; } if (result) { image->postExecutionUndoAdapter()->addCommand(toQShared(cmd.take())); } return result; }
void KisAslLayerStyleSerializerTest::testWritingGradients() { KoStopGradient stopGradient(""); { const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8(); QList<KoGradientStop> stops; stops << KoGradientStop(0.0, KoColor(Qt::black, cs)); stops << KoGradientStop(0.3, KoColor(Qt::red, cs)); stops << KoGradientStop(0.6, KoColor(Qt::green, cs)); stops << KoGradientStop(1.0, KoColor(Qt::white, cs)); stopGradient.setStops(stops); } KisPSDLayerStyleSP style(new KisPSDLayerStyle()); style->outerGlow()->setEffectEnabled(true); style->outerGlow()->setFillType(psd_fill_gradient); style->outerGlow()->setGradient(toQShared(new KoStopGradient(stopGradient))); style->innerGlow()->setEffectEnabled(true); style->innerGlow()->setFillType(psd_fill_gradient); style->innerGlow()->setGradient(toQShared(new KoStopGradient(stopGradient))); style->gradientOverlay()->setEffectEnabled(true); style->gradientOverlay()->setGradient(toQShared(new KoStopGradient(stopGradient))); style->stroke()->setEffectEnabled(true); style->stroke()->setFillType(psd_fill_gradient); style->stroke()->setGradient(toQShared(new KoStopGradient(stopGradient))); { KisAslLayerStyleSerializer s; s.setStyles(QVector<KisPSDLayerStyleSP>() << style); QFile dstFile("test_written_stop_gradient.asl"); dstFile.open(QIODevice::WriteOnly); s.saveToDevice(&dstFile); dstFile.close(); } QString xmlDoc; { QFile resultFile("test_written_stop_gradient.asl"); resultFile.open(QIODevice::ReadOnly); KisAslReader reader; QDomDocument doc = reader.readFile(&resultFile); xmlDoc = doc.toString(); } { // the reference document has stripped "Idnt" field which is random QRegExp rx("<node key=\"Idnt\" type=\"Text\" value=\".+\"/>"); rx.setMinimal(true); int pos = 0; while ((pos = rx.indexIn(xmlDoc, pos)) != -1) { xmlDoc.remove(pos, rx.matchedLength()); } { //QFile xmlFile("reference_gradients.asl.xml"); //xmlFile.open(QIODevice::WriteOnly); //xmlFile.write(xmlDoc.toLatin1()); //xmlFile.close(); } QString refFileName(TestUtil::fetchDataFileLazy("reference_gradients.asl.xml")); QFile refFile(refFileName); refFile.open(QIODevice::ReadOnly); QString refDoc = QString(refFile.readAll()); QCOMPARE(xmlDoc, refDoc); } }
QList<KisUniformPaintOpPropertySP> KisBrushBasedPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings) { QList<KisUniformPaintOpPropertySP> props = listWeakToStrong(m_uniformProperties); if (props.isEmpty()) { { KisIntSliderBasedPaintOpPropertyCallback *prop = new KisIntSliderBasedPaintOpPropertyCallback( KisIntSliderBasedPaintOpPropertyCallback::Int, "angle", "Angle", settings, 0); prop->setRange(0, 360); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast<KisBrushBasedPaintOpSettings*>(prop->settings().data()); const qreal angleResult = kisRadiansToDegrees(s->angle()); prop->setValue(angleResult); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast<KisBrushBasedPaintOpSettings*>(prop->settings().data()); s->setAngle(kisDegreesToRadians(prop->value().toReal())); }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisUniformPaintOpPropertyCallback *prop = new KisUniformPaintOpPropertyCallback( KisUniformPaintOpPropertyCallback::Bool, "auto_spacing", "Auto Spacing", settings, 0); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast<KisBrushBasedPaintOpSettings*>(prop->settings().data()); prop->setValue(s->autoSpacingActive()); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast<KisBrushBasedPaintOpSettings*>(prop->settings().data()); s->setAutoSpacing(prop->value().toBool(), s->autoSpacingCoeff()); }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisDoubleSliderBasedPaintOpPropertyCallback *prop = new KisDoubleSliderBasedPaintOpPropertyCallback( KisDoubleSliderBasedPaintOpPropertyCallback::Double, "spacing", "Spacing", settings, 0); prop->setRange(0.01, 10); prop->setSingleStep(0.01); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast<KisBrushBasedPaintOpSettings*>(prop->settings().data()); const qreal value = s->autoSpacingActive() ? s->autoSpacingCoeff() : s->spacing(); prop->setValue(value); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { KisBrushBasedPaintOpSettings *s = dynamic_cast<KisBrushBasedPaintOpSettings*>(prop->settings().data()); if (s->autoSpacingActive()) { s->setAutoSpacing(true, prop->value().toReal()); } else { s->setSpacing(prop->value().toReal()); } }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } } return KisPaintOpSettings::uniformProperties(settings) + props; }
bool KisAnimationCurvesModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) return false; KisScalarKeyframeChannel *channel = m_d->getCurveAt(index)->channel(); KUndo2Command *command = m_d->undoCommand; switch (role) { case ScalarValueRole: { KisKeyframeSP keyframe = channel->keyframeAt(index.column()); if (keyframe) { if (!command) command = new KUndo2Command(kundo2_i18n("Adjust keyframe")); channel->setScalarValue(keyframe, value.toReal(), command); } else { if (!command) command = new KUndo2Command(kundo2_i18n("Insert keyframe")); auto *addKeyframeCommand = new KisScalarKeyframeChannel::AddKeyframeCommand( channel, index.column(), value.toReal(), command); addKeyframeCommand->redo(); } } break; case LeftTangentRole: case RightTangentRole: { KisKeyframeSP keyframe = channel->keyframeAt(index.column()); if (!keyframe) return false; QPointF leftTangent = (role == LeftTangentRole ? value.toPointF() : keyframe->leftTangent()); QPointF rightTangent = (role == RightTangentRole ? value.toPointF() : keyframe->rightTangent()); if (!command) command = new KUndo2Command(kundo2_i18n("Adjust tangent")); channel->setInterpolationTangents(keyframe, keyframe->tangentsMode(), leftTangent, rightTangent, command); } break; case InterpolationModeRole: { KisKeyframeSP keyframe = channel->keyframeAt(index.column()); if (!keyframe) return false; if (!command) command = new KUndo2Command(kundo2_i18n("Set interpolation mode")); channel->setInterpolationMode(keyframe, (KisKeyframe::InterpolationMode)value.toInt(), command); } break; case TangentsModeRole: { KisKeyframeSP keyframe = channel->keyframeAt(index.column()); if (!keyframe) return false; KisKeyframe::InterpolationTangentsMode mode = (KisKeyframe::InterpolationTangentsMode)value.toInt(); QPointF leftTangent = keyframe->leftTangent(); QPointF rightTangent = keyframe->rightTangent(); if (!command) command = new KUndo2Command(kundo2_i18n("Set interpolation mode")); channel->setInterpolationTangents(keyframe, mode, leftTangent, rightTangent, command); } break; default: return KisTimeBasedItemModel::setData(index, value, role); } if (command && !m_d->undoCommand) { image()->postExecutionUndoAdapter()->addCommand(toQShared(command)); } return true; }
bool moveKeyframes(KisImageSP image, const FrameItemList &srcFrames, const FrameItemList &dstFrames, bool copy, KUndo2Command *parentCommand) { if (srcFrames.size() != dstFrames.size()) return false; bool result = false; QScopedPointer<KUndo2Command> cmd( new KUndo2Command(!copy ? kundo2_i18np("Move Keyframe", "Move %1 Keyframes", srcFrames.size()) : kundo2_i18np("Copy Keyframe", "Copy %1 Keyframes", srcFrames.size()), parentCommand)); for (int i = 0; i < srcFrames.size(); i++) { const int srcTime = srcFrames[i].time; KisNodeSP srcNode = srcFrames[i].node; KisKeyframeChannel *srcChannel = srcNode->getKeyframeChannel(srcFrames[i].channel); const int dstTime = dstFrames[i].time; KisNodeSP dstNode = dstFrames[i].node; KisKeyframeChannel *dstChannel = dstNode->getKeyframeChannel(dstFrames[i].channel, true); if (srcNode == dstNode) { if (!srcChannel) continue; KisKeyframeSP srcKeyframe = srcChannel->keyframeAt(srcTime); if (srcKeyframe) { if (copy) { srcChannel->copyKeyframe(srcKeyframe, dstTime, cmd.data()); } else { srcChannel->moveKeyframe(srcKeyframe, dstTime, cmd.data()); } } } else { if (!srcChannel|| !dstChannel) continue; KisKeyframeSP srcKeyframe = srcChannel->keyframeAt(srcTime); if (!srcKeyframe) continue; dstChannel->copyExternalKeyframe(srcChannel, srcTime, dstTime, cmd.data()); if (!copy) { srcChannel->deleteKeyframe(srcKeyframe, cmd.data()); } } result = true; } if (parentCommand) { cmd.take(); } else if (result) { image->postExecutionUndoAdapter()->addCommand(toQShared(cmd.take())); } return result; }
void KisBrush::prepareBrushPyramid() const { if (!d->brushPyramid) { d->brushPyramid = toQShared(new KisQImagePyramid(brushTipImage())); } }
QList<KisUniformPaintOpPropertySP> KisDuplicateOpSettings::uniformProperties(KisPaintOpSettingsSP settings) { QList<KisUniformPaintOpPropertySP> props = listWeakToStrong(m_uniformProperties); if (props.isEmpty()) { { KisUniformPaintOpPropertyCallback *prop = new KisUniformPaintOpPropertyCallback( KisUniformPaintOpPropertyCallback::Bool, "clone_healing", i18n("Healing"), settings, 0); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { DuplicateOption option; option.readOptionSetting(prop->settings().data()); prop->setValue(option.duplicate_healing); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { DuplicateOption option; option.readOptionSetting(prop->settings().data()); option.duplicate_healing = prop->value().toBool(); option.writeOptionSetting(prop->settings().data()); }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } { KisUniformPaintOpPropertyCallback *prop = new KisUniformPaintOpPropertyCallback( KisUniformPaintOpPropertyCallback::Bool, "clone_movesource", i18n("Move Source"), settings, 0); prop->setReadCallback( [](KisUniformPaintOpProperty *prop) { DuplicateOption option; option.readOptionSetting(prop->settings().data()); prop->setValue(option.duplicate_move_source_point); }); prop->setWriteCallback( [](KisUniformPaintOpProperty *prop) { DuplicateOption option; option.readOptionSetting(prop->settings().data()); option.duplicate_move_source_point = prop->value().toBool(); option.writeOptionSetting(prop->settings().data()); }); QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue())); prop->requestReadValue(); props << toQShared(prop); } } return KisPaintOpSettings::uniformProperties(settings) + props; }