void KisSelectionTest::testSelectionActions()
{
    KisPixelSelectionSP pixelSelection = new KisPixelSelection();

    KisSelectionSP selection = new KisSelection();
    QVERIFY(selection->hasPixelSelection() == false);
    QVERIFY(selection->hasShapeSelection() == false);
    selection->setPixelSelection(pixelSelection);

    pixelSelection->select(QRect(0, 0, 20, 20));

    KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection());
    tmpSel->select(QRect(10, 0, 20, 20));

    pixelSelection->addSelection(tmpSel);
    QCOMPARE(pixelSelection->selectedExactRect(), QRect(0, 0, 30, 20));
    selection->updateProjection();
    QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 30, 20));

    pixelSelection->clear();
    pixelSelection->select(QRect(0, 0, 20, 20));

    pixelSelection->subtractSelection(tmpSel);
    selection->updateProjection();
    QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 10, 20));

    pixelSelection->clear();
    selection->updateProjection();
    pixelSelection->select(QRect(0, 0, 20, 20));

    pixelSelection->intersectSelection(tmpSel);
    selection->updateProjection();
    QCOMPARE(selection->selectedExactRect(), QRect(10, 0, 10, 20));
}
void KisSelectionTest::testSelectionComponents()
{

    KisSelectionSP selection = new KisSelection();
    QVERIFY(selection->hasPixelSelection() == false);
    QVERIFY(selection->hasShapeSelection() == false);
    QVERIFY(selection->pixelSelection() == 0);
    QVERIFY(selection->shapeSelection() == 0);

    KisPixelSelectionSP pixelSelection = selection->getOrCreatePixelSelection();
    QVERIFY(selection->pixelSelection() == pixelSelection);
    QVERIFY(selection->hasPixelSelection() == true);

    KisMaskSP mask = new KisTransparencyMask();
    mask->select(QRect(0, 0, 100, 100));
    QCOMPARE(mask->selection()->selectedRect(), QRect(0,0,128, 128));
    QCOMPARE(mask->selection()->selectedExactRect(), QRect(0, 0, 100, 100));
    selection = new KisSelection(0, mask);
    selection->updateProjection();
    QVERIFY(selection->hasPixelSelection() == true);
    QCOMPARE(selection->selectedRect(), QRect(0,0,128, 128));
    QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 100, 100));
}
void KisTransformProcessingVisitor::transformSelection(KisSelectionSP selection, KisUndoAdapter *adapter, const ProgressHelper &helper)
{
    if(selection->hasPixelSelection()) {
        transformPaintDevice(selection->pixelSelection(), adapter, helper);
    }

    if (selection->hasShapeSelection()) {
        KisTransformWorker tw(selection->projection(), m_sx, m_sy, m_shearx, m_sheary,
                              m_shearOrigin.x(), m_shearOrigin.y(),
                              m_angle, m_tx, m_ty, 0,
                              m_filter);

        KUndo2Command* command =
            selection->shapeSelection()->transform(tw.transform() * m_shapesCorrection);
        if (command) {
            adapter->addCommand(command);
        }
    }

    selection->updateProjection();
}
bool KisKraSaveVisitor::saveSelection(KisNode* node)
{
    KisSelectionSP selection;
    if (node->inherits("KisMask")) {
        selection = static_cast<KisMask*>(node)->selection();
    } else if (node->inherits("KisAdjustmentLayer")) {
        selection = static_cast<KisAdjustmentLayer*>(node)->internalSelection();
    } else if (node->inherits("KisGeneratorLayer")) {
        selection = static_cast<KisGeneratorLayer*>(node)->internalSelection();
    } else {
        return false;
    }

    bool retval = true;

    if (selection->hasPixelSelection()) {
        KisPaintDeviceSP dev = selection->pixelSelection();
        if (!savePaintDevice(dev, getLocation(node, DOT_PIXEL_SELECTION))) {
            m_errorMessages << i18n("Failed to save the pixel selection data for layer %1.", node->name());
            retval = false;
        }
    }
    if (selection->hasShapeSelection()) {
        m_store->pushDirectory();
        retval = m_store->enterDirectory(getLocation(node, DOT_SHAPE_SELECTION));
        if (retval) {
            KisShapeSelection* shapeSelection = dynamic_cast<KisShapeSelection*>(selection->shapeSelection());
            if (!shapeSelection) {
                retval = false;
            }

            if (retval && !shapeSelection->saveSelection(m_store)) {
                m_errorMessages << i18n("Failed to save the vector selection data for layer %1.", node->name());
                retval = false;
            }
        }
        m_store->popDirectory();
    }
    return retval;
}
bool KisMirrorVisitor::mirrorMask(KisMask* mask)
{
    KoProperties properties;
    KisSelectionSP selection = mask->selection();
    if (selection->hasPixelSelection()) {
        KisPaintDeviceSP dev = selection->pixelSelection();

        QString name;
        if (m_orientation == Qt::Horizontal) {
            name = i18n("Mirror Mask X");
        } else {
            name = i18n("Mirror Mask Y");
        }

        // TODO: use a selection transaction to cache the outline
        KisTransaction transaction(name, dev);

        QRect dirty;
        if (m_orientation == Qt::Horizontal) {
            dirty = KisTransformWorker::mirrorX(dev, m_image->width()/2.0f);
        } else {
            dirty = KisTransformWorker::mirrorY(dev, m_image->height()/2.0f);
        }
        mask->setDirty(dirty);
        transaction.commit(m_image->undoAdapter());
        dev->setDirty(dirty);
    }
/* TODO: Doesn't work correctly even thoush it's the same code as the shape layer
    if (selection->hasShapeSelection()) {
        if (m_orientation == Qt::Horizontal) {
            KisTransformVisitor visitor(m_image, -1.0, 1.0, 0.0, 0.0, 0.0, m_image->width(), 0, 0, 0, true);
            mask->accept(visitor);
        } else {
            KisTransformVisitor visitor(m_image, 1.0, -1.0, 0.0, 0.0, 0.0, 0, m_image->height(), 0, 0, true);
            mask->accept(visitor);
        }
    } */
    selection->updateProjection();
    return true;
}
void KisShapeSelectionTest::testAddChild()
{
    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisImageSP image = new KisImage(new KisUndoAdapter(0), 300, 300, cs, "test");

    KisSelectionSP selection = new KisSelection();
    QVERIFY(selection->hasPixelSelection() == false);
    QVERIFY(selection->hasShapeSelection() == false);
    KisPixelSelectionSP pixelSelection = selection->getOrCreatePixelSelection();

    pixelSelection->select(QRect(0, 0, 100, 100));
    // Selection is using the pixel selection as datamanager so no projection update
    // needed
    QCOMPARE(pixelSelection->selected(25, 25), MAX_SELECTED);
    QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 100, 100));

    QRect rect(50, 50, 100, 100);
    QTransform matrix;
    matrix.scale(1 / image->xRes(), 1 / image->yRes());
    rect = matrix.mapRect(rect);

    KoPathShape* shape = new KoPathShape();
    shape->setShapeId(KoPathShapeId);
    shape->moveTo(rect.topLeft());
    shape->lineTo(rect.topLeft() + QPointF(rect.width(), 0));
    shape->lineTo(rect.bottomRight());
    shape->lineTo(rect.topLeft() + QPointF(0, rect.height()));
    shape->close();
    shape->normalize();

    KisShapeSelection * shapeSelection = new KisShapeSelection(image, selection);
    selection->setShapeSelection(shapeSelection);
    shapeSelection->addShape(shape);

    QCOMPARE(pixelSelection->selected(25, 25), MAX_SELECTED);
    QCOMPARE(selection->selectedExactRect(), QRect(0, 0, 150, 150));

    selection->updateProjection();
}