Esempio n. 1
0
    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;
}
Esempio n. 3
0
void KisAnimationCurvesModel::endCommand()
{
    KIS_ASSERT_RECOVER_RETURN(m_d->undoCommand);
    image()->postExecutionUndoAdapter()->addCommand(toQShared(m_d->undoCommand));

    m_d->undoCommand = 0;
}
Esempio n. 4
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));
}
Esempio n. 6
0
    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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
    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;
    }
Esempio n. 11
0
void KisBrush::prepareBrushPyramid() const
{
    if (!d->brushPyramid) {
        d->brushPyramid = toQShared(new KisQImagePyramid(brushTipImage()));
    }
}
Esempio n. 12
0
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;
}