Пример #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;
    }
Пример #2
0
    void updateMask(bool isHidden) {
        /**
         * Depending on whether the mask is hidden we should either
         * update it entirely via the setDirty() call, or we can use a
         * lightweight approach by directly regenerating the
         * precalculated static image using
         * KisRecalculateTransformMaskJob.
         */

        if (!isHidden) {
            KisRecalculateTransformMaskJob updateJob(m_mask);
            updateJob.run();
        } else {
            m_mask->recaclulateStaticImage();

            QRect updateRect = m_mask->extent();

            KisNodeSP parent = m_mask->parent();
            if (parent && parent->original()) {
                updateRect |= parent->original()->defaultBounds()->bounds();
            }

            m_mask->setDirty(updateRect);
        }
    }
Пример #3
0
KisNodeSP KisKraLoader::loadNodes(const KoXmlElement& element, KisImageWSP image, KisNodeSP parent)
{

    KoXmlNode node = element.firstChild();
    KoXmlNode child;

    if (!node.isNull()) {

        if (node.isElement()) {

            if (node.nodeName().toUpper() == LAYERS.toUpper() || node.nodeName().toUpper() == MASKS.toUpper()) {
                for (child = node.lastChild(); !child.isNull(); child = child.previousSibling()) {
                    KisNodeSP node = loadNode(child.toElement(), image, parent);
                    if (node) {
                        image->nextLayerName(); // Make sure the nameserver is current with the number of nodes.
                        image->addNode(node, parent);
                        if (node->inherits("KisLayer") && child.childNodesCount() > 0) {
                            loadNodes(child.toElement(), image, node);
                        }
                    }
                }
            }
        }
    }

    return parent;
}
Пример #4
0
KisImageLayerRemoveCommand::KisImageLayerRemoveCommand(KisImageSP image, KisNodeSP layer)
        : KisImageCommand(i18n("Remove Layer"), image)
{
    m_layer = layer;
    m_prevParent = layer->parent();
    m_prevAbove = layer->prevSibling();
}
Пример #5
0
    void refreshLayerMovementAbilities()
    {
        layerMeta.clear();
        if (layers.count() == 0)
            return;
        for(int i = 0; i < layers.count(); ++i)
        {
            const KisNodeSP layer = layers.at(i);
            LayerModelMetaInfo ability;

            if (i > 0)
                ability.canMoveUp = true;

            if (i < layers.count() - 1)
                ability.canMoveDown = true;

            KisNodeSP parent = layer;
            while(parent)
            {
                ++ability.depth;
                parent = parent->parent();
            }

            if (ability.depth > 1)
                ability.canMoveLeft = true;

            if (i < layers.count() - 1 && qobject_cast<const KisGroupLayer*>(layers.at(i + 1).constData()))
                ability.canMoveRight = true;

            layerMeta[layer] = ability;
        }
    }
Пример #6
0
QRect KisFilterMask::needRect(const QRect& rect, PositionToFilthy pos) const
{
    Q_UNUSED(pos);

    /**
     * FIXME: This check of the emptiness should be done
     * on the higher/lower level
     */

    if(rect.isEmpty()) return rect;

    KisSafeFilterConfigurationSP filterConfig = filter();
    if (!filterConfig) return rect;

    KisNodeSP parent = this->parent();
    const int lod = parent && parent->projection() ?
        parent->projection()->defaultBounds()->currentLevelOfDetail() : 0;

    KisFilterSP filter = KisFilterRegistry::instance()->value(filterConfig->name());

    /**
     * If we need some additional pixels even outside of a selection
     * for accurate layer filtering, we'll get them!
     * And no KisMask::needRect will prevent us from doing this! ;)
     * That's why simply we do not call KisMask::needRect here :)
     */
    return filter->neededRect(rect, filterConfig.data(), lod);
}
Пример #7
0
/**
 * FIXME: try to cache filter pointer inside a Private block
 */
QRect KisFilterMask::changeRect(const QRect &rect, PositionToFilthy pos) const
{
    /**
     * FIXME: This check of the emptiness should be done
     * on the higher/lower level
     */
    if(rect.isEmpty()) return rect;

    QRect filteredRect = rect;

    KisSafeFilterConfigurationSP filterConfig = filter();
    if (filterConfig) {
        KisNodeSP parent = this->parent();
        const int lod = parent && parent->projection() ?
            parent->projection()->defaultBounds()->currentLevelOfDetail() : 0;

        KisFilterSP filter = KisFilterRegistry::instance()->value(filterConfig->name());
        filteredRect = filter->changedRect(rect, filterConfig.data(), lod);
    }

    /**
     * We can't paint outside a selection, that is why we call
     * KisMask::changeRect to crop actual change area in the end
     */
    filteredRect = KisMask::changeRect(filteredRect, pos);
    /**
     * FIXME: Think over this solution
     * Union of rects means that changeRect returns NOT the rect
     * changed by this very layer, but an accumulated rect changed
     * by all underlying layers. Just take into account and change
     * documentation accordingly
     */
    return rect | filteredRect;
}
Пример #8
0
KisImageCommand::UpdateTarget::UpdateTarget(KisImageWSP image,
                                            KisNodeSP removedNode,
                                            const QRect &updateRect)
    : m_image(image), m_updateRect(updateRect)
{
    m_needsFullRefresh = false;

    if(!isLayer(removedNode)) {
        m_node = removedNode->parent();
    }
    else {
        m_node = removedNode;
        while((m_node = m_node->nextSibling()) && !isLayer(m_node));

        if(!m_node) {
            m_node = removedNode;
            while((m_node = m_node->prevSibling()) && !isLayer(m_node));
        }

        if(!m_node) {
            m_node = removedNode->parent();
            m_needsFullRefresh = true;
        }
    }
}
Пример #9
0
bool KisNodeFacade::moveNode(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis)
{
    dbgImage << "moveNode " << node << " " << parent << " " << aboveThis;
    if (!node) {
        dbgImage << "cannot move null node"; return false;
    }
    if (!parent)  {
        dbgImage << "cannot move to null parent"; return false;
    }
    if (node == parent)  {
        dbgImage << "cannot move self inside self"; return false;
    }
    if (node == aboveThis)  {
        dbgImage << "cannot move self above self"; return false;
    }
    if (parent == aboveThis)  {
        dbgImage << "cannot move above parent"; return false;
    }
    if (!node->parent())  {
        dbgImage << "node does not have a parent"; return false;
    }

    if (aboveThis && aboveThis->parent() != parent)  {
        dbgImage << "above this parent is not the parent"; return false;
    }

    int newIndex = aboveThis ? parent->index(aboveThis) + 1 : 0;
    return moveNode(node, parent, newIndex);
}
Пример #10
0
    KisNodeSP findNode(KisNodeSP node, const QPoint &point, bool wholeGroup, bool editableOnly)
    {
        KisNodeSP foundNode = 0;
        while (node) {
            KisLayerSP layer = dynamic_cast<KisLayer*>(node.data());

            if (!layer || !layer->isEditable()) {
                node = node->prevSibling();
                continue;
            }

            KoColor color(layer->projection()->colorSpace());
            layer->projection()->pixel(point.x(), point.y(), &color);

            KisGroupLayerSP group = dynamic_cast<KisGroupLayer*>(layer.data());

            if ((group && group->passThroughMode()) ||  color.opacityU8() != OPACITY_TRANSPARENT_U8) {
                if (layer->inherits("KisGroupLayer") && (!editableOnly || layer->isEditable())) {
                    // if this is a group and the pixel is transparent, don't even enter it
                    foundNode = findNode(node->lastChild(), point, wholeGroup, editableOnly);
                }
                else {
                    foundNode = !wholeGroup ? node : node->parent();
                }

            }

            if (foundNode) break;

            node = node->prevSibling();
        }

        return foundNode;
    }
void KisCutCopyActionFactory::run(bool willCut, KisView2 *view)
{
    KisImageSP image = view->image();
    bool haveShapesSelected = view->selectionManager()->haveShapesSelected();

    if (haveShapesSelected) {
#ifdef __GNUC__
#warning "Add saving of XML data for Cut/Copy of shapes"
#endif

        image->barrierLock();
        if (willCut) {
            view->canvasBase()->toolProxy()->cut();
        } else {
            view->canvasBase()->toolProxy()->copy();
        }
        image->unlock();
    } else {
        KisNodeSP node = view->activeNode();
        if (!node) return;

        image->barrierLock();
        ActionHelper::copyFromDevice(view, node->paintDevice());
        image->unlock();

        KUndo2Command *command = 0;

        if (willCut && node->isEditable()) {
            struct ClearSelection : public KisTransactionBasedCommand {
                ClearSelection(KisNodeSP node, KisSelectionSP sel)
                    : m_node(node), m_sel(sel) {}
                KisNodeSP m_node;
                KisSelectionSP m_sel;

                KUndo2Command* paint() {
                    KisTransaction transaction("", m_node->paintDevice());
                    m_node->paintDevice()->clearSelection(m_sel);
                    m_node->setDirty(m_sel->selectedRect());
                    return transaction.endAndTake();
                }
            };

            command = new ClearSelection(node, view->selection());
        }

        QString actionName = willCut ? i18n("Cut") : i18n("Copy");
        KisProcessingApplicator *ap = beginAction(view, actionName);

        if (command) {
            ap->applyCommand(command,
                             KisStrokeJobData::SEQUENTIAL,
                             KisStrokeJobData::NORMAL);
        }

        KisOperationConfiguration config(id());
        config.setProperty("will-cut", willCut);
        endAction(ap, config.toXML());
    }
}
Пример #12
0
bool KisNodeFacade::removeNode(KisNodeSP node)
{
    if (!node) return false;
    if (!node->parent()) return false;

    return node->parent()->remove(node);

}
Пример #13
0
 int deepChildCount(KisNodeSP layer)
 {
     quint32 childCount = layer->childCount();
     QList<KisNodeSP> children = layer->childNodes(layerClassNames(), KoProperties());
     for(quint32 i = 0; i < childCount; ++i)
         childCount += deepChildCount(children.at(i));
     return childCount;
 }
Пример #14
0
KisNodeSP KisDummiesFacadeBase::findFirstLayer(KisNodeSP root)
{
    KisNodeSP child = root->firstChild();
    while(child && !child->inherits("KisLayer")) {
        child = child->nextSibling();
    }
    return child;
}
Пример #15
0
bool KisNodeFacade::toTop(KisNodeSP node)
{
    if (!node) return false;
    if (!node->parent()) return false;
    if (node == node->parent()->lastChild()) return true;

    return moveNode(node, node->parent(), node->parent()->lastChild());

}
Пример #16
0
 MoveNodeStruct(KisImageSP _image, KisNodeSP _node, KisNodeSP _parent, KisNodeSP _above)
     : image(_image),
       node(_node),
       newParent(_parent),
       newAbove(_above),
       oldParent(_node->parent()),
       oldAbove(_node->prevSibling())
 {
 }
QImage utils::StrokeTester::doStroke(bool cancelled,
                                     bool indirectPainting,
                                     bool externalLayer,
                                     bool testUpdates,
                                     bool needQImage)
{
    KisImageSP image = utils::createImage(0, m_imageSize);
    KoCanvasResourceManager *manager = utils::createResourceManager(image, 0, m_presetFilename);
    KisNodeSP currentNode;

    for (int i = 0; i < m_numIterations; i++) {
        modifyResourceManager(manager, image, i);

        KisPainter *painter = new KisPainter();
        KisResourcesSnapshotSP resources =
            new KisResourcesSnapshot(image,
                                     image->rootLayer()->firstChild(),
                                     image->postExecutionUndoAdapter(),
                                     manager);

        if(externalLayer) {
            KisNodeSP externalNode = new KisPaintLayer(0, "extlyr", OPACITY_OPAQUE_U8, image->colorSpace());
            resources->setCurrentNode(externalNode);
            Q_ASSERT(resources->currentNode() == externalNode);
        }

        initImage(image, resources->currentNode(), i);

        KisStrokeStrategy *stroke = createStroke(indirectPainting, resources, painter, image);
        m_strokeId = image->startStroke(stroke);
        addPaintingJobs(image, resources, painter, i);

        if(!cancelled) {
            image->endStroke(m_strokeId);
        }
        else {
            image->cancelStroke(m_strokeId);
        }

        image->waitForDone();
        currentNode = resources->currentNode();
    }

    QImage resultImage;
    if(needQImage) {
        KisPaintDeviceSP device = testUpdates ?
            image->projection() :
            currentNode->paintDevice();

        resultImage = device->convertToQImage(0, 0, 0, image->width(), image->height());
    }

    image = 0;
    delete manager;
    return resultImage;
}
Пример #18
0
void KisDummiesFacadeBase::slotNodeAdded(KisNodeSP node)
{
    emit sigContinueAddNode(node, node->parent(), node->prevSibling());

    KisNodeSP childNode = node->firstChild();
    while (childNode) {
        slotNodeAdded(childNode);
        childNode = childNode->nextSibling();
    }
}
Пример #19
0
KisImageLayerMoveCommand::KisImageLayerMoveCommand(KisImageSP image, KisNodeSP layer, KisNodeSP newParent, KisNodeSP newAbove)
        : KisImageCommand(i18n("Move Layer"), image)
{
    m_layer = layer;
    m_newParent = newParent;
    m_newAbove = newAbove;
    m_prevParent = layer->parent();
    m_prevAbove = layer->prevSibling();
    m_index = -1;
}
Пример #20
0
KisImageLayerMoveCommand::KisImageLayerMoveCommand(KisImageSP image, KisNodeSP node, KisNodeSP newParent, quint32 index)
        : KisImageCommand(i18n("Move Layer"), image)
{
    m_layer = node;
    m_newParent = newParent;
    m_newAbove = 0;
    m_prevParent = node->parent();
    m_prevAbove = node->prevSibling();
    m_index = index;
}
Пример #21
0
void KisDummiesFacadeBase::slotRemoveNode(KisNodeSP node)
{
    KisNodeSP childNode = node->lastChild();
    while (childNode) {
        slotRemoveNode(childNode);
        childNode = childNode->prevSibling();
    }

    emit sigContinueRemoveNode(node);
}
Пример #22
0
void testObligeSingleChildImpl(bool transpDefaultPixel)
{

    QString id = !transpDefaultPixel ?
        "single_layer_no_channel_flags_nontransp_def_pixel.kra" :
        "single_layer_no_channel_flags_transp_def_pixel.kra";

    QString fileName = TestUtil::fetchDataFileLazy(id);

    KisDocument *doc = KisPart::instance()->createDocument();
    doc->loadNativeFormat(fileName);
    KisImageWSP image = doc->image();

    QVERIFY(image);
    QCOMPARE(image->nlayers(), 2);

    KisNodeSP root = image->root();
    KisNodeSP child = root->firstChild();

    QVERIFY(child);

    QCOMPARE(root->original(), root->projection());

    if (transpDefaultPixel) {
        QCOMPARE(root->original(), child->projection());
    } else {
        QVERIFY(root->original() != child->projection());
    }

    delete doc;
}
Пример #23
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;
    }
Пример #24
0
bool KisNodeFacade::addNode(KisNodeSP node, KisNodeSP parent)
{
    dbgImage << "Add node " << node << " to " << parent;
    if (!node) return false;
    if (!parent && !m_d->root) return false;

    if (parent)
        return parent->add(node, parent->lastChild());
    else
        return m_d->root->add(node, m_d->root->lastChild());
}
Пример #25
0
bool KisNodeFacade::lowerNode(KisNodeSP node)
{
    if (!node) return false;
    if (!node->parent()) return false;

    if (node->prevSibling())
        return raiseNode(node->prevSibling());
    else
        return true; // We're already at bottom, but there's no sense
    // in complaining
}
void KisClearActionFactory::run(KisView2 *view)
{
#ifdef __GNUC__
#warning "Add saving of XML data for Clear action"
#endif

    KisNodeSP node = view->activeNode();
    if (!node || !node->isEditable()) return;

    view->canvasBase()->toolProxy()->deleteSelection();
}
Пример #27
0
KisImageLayerMoveCommand::KisImageLayerMoveCommand(KisImageWSP image, KisNodeSP layer, KisNodeSP newParent, KisNodeSP newAbove, bool doUpdates)
        : KisImageCommand(kundo2_i18n("Move Layer"), image)
{
    m_layer = layer;
    m_newParent = newParent;
    m_newAbove = newAbove;
    m_prevParent = layer->parent();
    m_prevAbove = layer->prevSibling();
    m_index = -1;
    m_useIndex = false;
    m_doUpdates = doUpdates;
}
Пример #28
0
KisImageLayerMoveCommand::KisImageLayerMoveCommand(KisImageWSP image, KisNodeSP node, KisNodeSP newParent, quint32 index)
        : KisImageCommand(kundo2_i18n("Move Layer"), image)
{
    m_layer = node;
    m_newParent = newParent;
    m_newAbove = 0;
    m_prevParent = node->parent();
    m_prevAbove = node->prevSibling();
    m_index = index;
    m_useIndex = true;
    m_doUpdates = true;
}
Пример #29
0
bool KisNodeFacade::raiseNode(KisNodeSP node)
{
    if (!node) return false;
    if (!node->parent()) return false;

    if (node->nextSibling())
        return moveNode(node, node->parent(), node->nextSibling());
    else
        return true; // we're already at the top, but there is no
    // sense in complaining.

}
Пример #30
0
void dumpNodeStack(KisNodeSP node, QString prefix = QString("\t"))
{
    for (uint i = 0; i < node->childCount(); ++i) {
        if (node->at(i)->parent())
            dbgImage << prefix << "\t" << node->at(i) << "node at" << i << " has index from parent:" << node->index(node->at(i));

        if (node->at(i)->childCount() > 0) {
            dumpNodeStack(node->at(i), prefix + "\t");
        }
    }

}