void KisSelectionToolHelper::addSelectionShapes(QList< KoShape* > shapes)
{
    KisViewManager* view = m_canvas->viewManager();

    if (view->image()->wrapAroundModePermitted()) {
        view->showFloatingMessage(
            i18n("Shape selection does not fully "
                 "support wraparound mode. Please "
                 "use pixel selection instead"),
                 KisIconUtils::loadIcon("selection-info"));
    }

    KisProcessingApplicator applicator(view->image(),
                                       0 /* we need no automatic updates */,
                                       KisProcessingApplicator::NONE,
                                       KisImageSignalVector() << ModifiedSignal,
                                       m_name);

    applicator.applyCommand(new LazyInitGlobalSelection(view));

    struct ClearPixelSelection : public KisTransactionBasedCommand {
        ClearPixelSelection(KisViewManager *view) : m_view(view) {}
        KisViewManager *m_view;

        KUndo2Command* paint() {

            KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection();
            KIS_ASSERT_RECOVER(pixelSelection) { return 0; }

            KisSelectionTransaction transaction(pixelSelection);
            pixelSelection->clear();
            return transaction.endAndTake();
        }
    };

    applicator.applyCommand(new ClearPixelSelection(view));

    struct AddSelectionShape : public KisTransactionBasedCommand {
        AddSelectionShape(KisViewManager *view, KoShape* shape) : m_view(view),
                                                            m_shape(shape) {}
        KisViewManager *m_view;
        KoShape* m_shape;

        KUndo2Command* paint() {
            /**
             * Mark a shape that it belongs to a shape selection
             */
            if(!m_shape->userData()) {
                m_shape->setUserData(new KisShapeSelectionMarker);
            }

            return m_view->canvasBase()->shapeController()->addShape(m_shape);
        }
    };

    foreach(KoShape* shape, shapes) {
        applicator.applyCommand(
            new KisGuiContextCommand(new AddSelectionShape(view, shape), view));
    }
void KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action)
{
    KisViewManager* view = m_canvas->viewManager();

    if (selection->selectedExactRect().isEmpty()) {
        m_canvas->viewManager()->selectionManager()->deselect();
        return;
    }

    KisProcessingApplicator applicator(view->image(),
                                       0 /* we need no automatic updates */,
                                       KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE,
                                       KisImageSignalVector() << ModifiedSignal,
                                       m_name);

    applicator.applyCommand(new LazyInitGlobalSelection(view));

    struct ApplyToPixelSelection : public KisTransactionBasedCommand {
        ApplyToPixelSelection(KisViewManager *view,
                              KisPixelSelectionSP selection,
                              SelectionAction action) : m_view(view),
                                                        m_selection(selection),
                                                        m_action(action) {}
        KisViewManager *m_view;
        KisPixelSelectionSP m_selection;
        SelectionAction m_action;

        KUndo2Command* paint() {

            KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection();
            KIS_ASSERT_RECOVER(pixelSelection) { return 0; }

            bool hasSelection = !pixelSelection->isEmpty();

            KisSelectionTransaction transaction(pixelSelection);

            if (!hasSelection && m_action == SELECTION_SUBTRACT) {
                pixelSelection->invert();
            }

            pixelSelection->applySelection(m_selection, m_action);

            QRect dirtyRect = m_view->image()->bounds();
            if (hasSelection && m_action != SELECTION_REPLACE && m_action != SELECTION_INTERSECT) {
                dirtyRect = m_selection->selectedRect();
            }
            m_view->selection()->updateProjection(dirtyRect);

            KUndo2Command *savedCommand = transaction.endAndTake();
            pixelSelection->setDirty(dirtyRect);

            return savedCommand;
        }
    };

    applicator.applyCommand(new ApplyToPixelSelection(view, selection, action));
    applicator.end();
}
void KisFillActionFactory::run(const QString &fillSource, KisViewManager *view)
{
    KisNodeSP node = view->activeNode();
    if (!node || !node->hasEditablePaintDevice()) return;

    KisSelectionSP selection = view->selection();
    QRect selectedRect = selection ?
                         selection->selectedRect() : view->image()->bounds();
    Q_UNUSED(selectedRect);
    KisPaintDeviceSP filled = node->paintDevice()->createCompositionSourceDevice();
    Q_UNUSED(filled);
    bool usePattern = false;
    bool useBgColor = false;

    if (fillSource.contains("pattern")) {
        usePattern = true;
    } else if (fillSource.contains("bg")) {
        useBgColor = true;
    }

    KisProcessingApplicator applicator(view->image(), node,
                                       KisProcessingApplicator::NONE,
                                       KisImageSignalVector() << ModifiedSignal,
                                       kundo2_i18n("Flood Fill Layer"));

    KisResourcesSnapshotSP resources =
        new KisResourcesSnapshot(view->image(), node, 0, view->resourceProvider()->resourceManager());
    if (!fillSource.contains("opacity")) {
        resources->setOpacity(1.0);
    }

    KisProcessingVisitorSP visitor =
        new FillProcessingVisitor(QPoint(0, 0), // start position
                                  selection,
                                  resources,
                                  false, // fast mode
                                  usePattern,
                                  true, // fill only selection,
                                  0, // feathering radius
                                  0, // sizemod
                                  80, // threshold,
                                  false, // unmerged
                                  useBgColor);

    applicator.applyVisitor(visitor,
                            KisStrokeJobData::SEQUENTIAL,
                            KisStrokeJobData::EXCLUSIVE);

    applicator.end();
}
void KisSelectionDecorationTest::testConcurrentSelectionFetches()
{
    KisImageSP image = utils::createImage(0, QSize(3000, 3000));

    for (int i = 0; i < 10000; i++) {
        KisProcessingApplicator applicator(image,
                                           0 /* we need no automatic updates */,
                                           KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE,
                                           KisImageSignalVector() << ModifiedSignal,
                                           kundo2_noi18n("test stroke"));


        applicator.applyCommand(new KisSetEmptyGlobalSelectionCommand(image));
        applicator.applyCommand(new KisDeselectGlobalSelectionCommand(image));

        applicator.end();

        for (int j = 0; j < 100; j++) {
            KisSelectionSP selection = image->globalSelection();
        }
    }

    image->waitForDone();
}
Exemplo n.º 5
0
void KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action)
{
    KisViewManager* view = m_canvas->viewManager();

    if (selection->selectedExactRect().isEmpty()) {
        m_canvas->viewManager()->selectionManager()->deselect();
        return;
    }

    KisProcessingApplicator applicator(view->image(),
                                       0 /* we need no automatic updates */,
                                       KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE,
                                       KisImageSignalVector() << ModifiedSignal,
                                       m_name);

    applicator.applyCommand(new LazyInitGlobalSelection(view));

    struct ApplyToPixelSelection : public KisTransactionBasedCommand {
        ApplyToPixelSelection(KisViewManager *view,
                              KisPixelSelectionSP selection,
                              SelectionAction action) : m_view(view),
                                                        m_selection(selection),
                                                        m_action(action) {}
        KisViewManager *m_view;
        KisPixelSelectionSP m_selection;
        SelectionAction m_action;

        KUndo2Command* paint() override {

            KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection();
            KIS_ASSERT_RECOVER(pixelSelection) { return 0; }

            bool hasSelection = !pixelSelection->isEmpty();

            KisSelectionTransaction transaction(pixelSelection);

            if (!hasSelection && m_action == SELECTION_SUBTRACT) {
                pixelSelection->invert();
            }

            pixelSelection->applySelection(m_selection, m_action);

            const QRect imageBounds = m_view->image()->bounds();
            QRect selectionExactRect = m_view->selection()->selectedExactRect();

            if (!imageBounds.contains(selectionExactRect)) {
                pixelSelection->crop(imageBounds);
                if (pixelSelection->outlineCacheValid()) {
                    QPainterPath cache = pixelSelection->outlineCache();
                    QPainterPath imagePath;
                    imagePath.addRect(imageBounds);
                    cache &= imagePath;
                    pixelSelection->setOutlineCache(cache);
                }
                selectionExactRect &= imageBounds;
            }

            QRect dirtyRect = imageBounds;
            if (hasSelection && m_action != SELECTION_REPLACE && m_action != SELECTION_INTERSECT) {
                dirtyRect = m_selection->selectedRect();
            }
            m_view->selection()->updateProjection(dirtyRect);

            KUndo2Command *savedCommand = transaction.endAndTake();
            pixelSelection->setDirty(dirtyRect);

            if (selectionExactRect.isEmpty()) {
                KisCommandUtils::CompositeCommand *cmd = new KisCommandUtils::CompositeCommand();
                cmd->addCommand(savedCommand);
                cmd->addCommand(new KisDeselectGlobalSelectionCommand(m_view->image()));
                savedCommand = cmd;
            }

            return savedCommand;
        }
    };

    applicator.applyCommand(new ApplyToPixelSelection(view, selection, action));
    applicator.end();
}