KoShape *KPrPlaceholderPictureStrategy::createShape(KoDocumentResourceManager *rm)
{
    KoShape * shape = 0;

    KUrl url = KFileDialog::getOpenUrl();
    if ( !url.isEmpty() ) {
        shape = KPrPlaceholderStrategy::createShape(rm);

        KoImageCollection *collection = rm->imageCollection();
        Q_ASSERT(collection);

        QString tmpFile;
        if (KIO::NetAccess::download(url, tmpFile, 0)) {
            QImage image(tmpFile);
            if (!image.isNull()) {
                //setSuffix(url.prettyUrl());
                KoImageData *data = collection->createImageData(image);
                if (data->isValid()) {
                    shape->setUserData( data );
                    // TODO the pic should be fit into the space provided
                    shape->setSize( data->imageSize() );
                }
            }
        } else {
            kWarning() << "open image " << url.prettyUrl() << "failed";
        }
    }
    return shape;
}
Пример #2
0
void PictureShape::saveOdf(KoShapeSavingContext &context) const
{
    // make sure we have a valid image data pointer before saving
    KoImageData *imageData = qobject_cast<KoImageData*>(userData());
    if (imageData == 0) {
        return;
    }

    KoXmlWriter &writer = context.xmlWriter();

    writer.startElement("draw:frame");
    saveOdfAttributes(context, OdfAllAttributes);
    writer.startElement("draw:image");
    // In the spec, only the xlink:href attribute is marked as mandatory, cool :)
    QString name = context.imageHref(imageData);
    writer.addAttribute("xlink:type", "simple");
    writer.addAttribute("xlink:show", "embed");
    writer.addAttribute("xlink:actuate", "onLoad");
    writer.addAttribute("xlink:href", name);
    saveText(context);
    writer.endElement(); // draw:image
    QSizeF scaleFactor(imageData->imageSize().width() / size().width(),
                  imageData->imageSize().height() / size().height());
    saveOdfClipContour(context, scaleFactor);
    writer.endElement(); // draw:frame

    context.addDataCenter(m_imageCollection);
}
Пример #3
0
void PictureShape::waitUntilReady(const KoViewConverter &converter, bool asynchronous) const
{
    KoImageData *imageData = qobject_cast<KoImageData*>(userData());
    if (imageData == 0) {
        return;
    }

    if (asynchronous) {
        // get pixmap and schedule it if not
        QSize pixels = converter.documentToView(QRectF(QPointF(0,0), size())).size().toSize();
        QImage image = imageData->image();
        if (image.isNull()) {
            return;
        }
        m_printQualityRequestedSize = pixels;
        if (image.size().width() < pixels.width()) { // don't scale up.
            pixels = image.size();
        }
        m_printQualityImage = image.scaled(pixels, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    }
    else {
        QSize pixmapSize = calcOptimalPixmapSize(converter.documentToView(QRectF(QPointF(0,0), size())).size(), imageData->image().size());
        QString key(generate_key(imageData->key(), pixmapSize));
        if (QPixmapCache::find(key) == 0) {
            QPixmap pixmap = imageData->pixmap(pixmapSize);
            QPixmapCache::insert(key, pixmap);
        }
    }
}
Пример #4
0
bool PictureShape::loadFromUrl( KUrl &url )
{
    KoImageData * data = m_imageCollection->getImage(url);
    if ( data ) {
        setUserData( data );
        // don't set the size of the shape to the size of the picture, but instead keep the
        // area of the shape constant, and only change the aspect ratio to be that of the image
        QSizeF oldsize = size();
        QSizeF newsize = data->imageSize();
        qreal oldarea = oldsize.width() * oldsize.height();
        qreal newarea = newsize.width() * newsize.height();
        newsize *= sqrt(oldarea / newarea);
        setSize(newsize);
    }
    return data != 0;
}
Пример #5
0
void KritaShape::waitUntilReady() const
{
    if (m_d && m_d->doc && m_d->doc->image())   // all done
        return;

    KoImageData *data = dynamic_cast<KoImageData*>(KoShape::userData());
    if (data == 0 || data->image().isNull())
        return; // no data available at all, so don't try to wait later on.

    KritaShape *me = const_cast<KritaShape*>(this);

    m_mutex.lock();
    me->tryLoadFromImageData(data);
    m_waiter.wait(&m_mutex);
    m_mutex.unlock();
}
Пример #6
0
void KPrPicturesImport::pictureImported(KJob *job)
{
    KoShape *shape = m_factory->createDefaultShape();
    if (shape) {
        KIO::StoredTransferJob *transferJob = qobject_cast<KIO::StoredTransferJob*>(job);
        Q_ASSERT(transferJob);
        KoImageData *imageData = m_doc->resourceManager()->imageCollection()->createImageData(transferJob->data());
        if (imageData->isValid()) {
            shape->setUserData(imageData);

            // make sure the picture fits on the page
            QSizeF imageSize = imageData->imageSize();
            QSizeF pageSize = m_masterPage->size();
            qreal zoom = 1;
            if (imageSize.width() > pageSize.width() || imageSize.height() > pageSize.height()) {
                zoom = pageSize.width() / imageSize.width();
                zoom = qMin(zoom, pageSize.height() / imageSize.height());
            }
            imageSize *= zoom;
            shape->setSize(imageSize);

            // center the picture on the page
            QPointF pos( pageSize.width() / 2- imageSize.width() / 2, pageSize.height() / 2 - imageSize.height() / 2 );
            shape->setPosition(pos);

            KoPAPageBase *page = m_doc->newPage(m_masterPage);
            KoShapeLayer *layer = dynamic_cast<KoShapeLayer *>(page->shapes().first());
            if (layer) {
                layer->addShape(shape);
                new KoPAPageInsertCommand(m_doc, page, m_currentPage, m_cmd);
                m_currentPage = page;
            }
            else {
                delete page;
                delete shape;
            }
        }
        else {
            kWarning(33001) << "imageData not valid";
            delete shape;
        }
    }
    else {
        kWarning(33001) << "shape not created";
    }
    import();
}
KoShape *PictureShapeFactory::createShape(const KoProperties *params, KoDocumentResourceManager *documentResources) const
{
    PictureShape *shape = static_cast<PictureShape*>(createDefaultShape(documentResources));
    if (params->contains("qimage")) {
        QImage image = params->property("qimage").value<QImage>();
        Q_ASSERT(!image.isNull());

        if (shape->imageCollection()) {
            KoImageData *data = shape->imageCollection()->createImageData(image);
            shape->setUserData(data);
            shape->setSize(data->imageSize());
            shape->update();
        }
    }
    return shape;

}
Пример #8
0
KoShape * KPrPlaceholderPictureStrategy::createShape( const QMap<QString, KoDataCenter *> & dataCenterMap )
{
    KoShape * shape = 0;

    KUrl url = KFileDialog::getOpenUrl();
    if ( !url.isEmpty() ) {
        shape = KPrPlaceholderStrategy::createShape( dataCenterMap );

        KoImageCollection * collection = dynamic_cast<KoImageCollection *>( dataCenterMap.value( "ImageCollection" ) );
        KoImageData * data = collection->getImage( url );
        if ( data ) {
            shape->setUserData( data );
            // TODO th pic should be fit into the space provided
            shape->setSize( data->imageSize() );
        }
    }
    return shape;
}
void LoadWaiter::setImageData(const QImage &image)
{
    if (m_pictureShape == 0)
        return; // ugh, the shape got deleted meanwhile
    //KIO::StoredTransferJob *transferJob = qobject_cast<KIO::StoredTransferJob*>(job);
    //Q_ASSERT(transferJob);

    if (m_pictureShape->imageCollection()) {
        KoImageData *data = m_pictureShape->imageCollection()->createImageData(image);
        if (data) {
            m_pictureShape->setUserData(data);
            // check if the shape still size of the default shape and resize in that case
            if (qFuzzyCompare(m_pictureShape->size().width(), 50.0)) {
                m_pictureShape->setSize(data->imageSize());
            }
        }
    }
    deleteLater();
}
Пример #10
0
bool PictureShape::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context)
{
    loadOdfAttributes(element, context, OdfAllAttributes);

    if (loadOdfFrame(element, context)) {
        // load contour (clip)
        KoImageData *imageData = qobject_cast<KoImageData*>(userData());

        QSizeF scaleFactor(size().width() / imageData->imageSize().width(),
                 size().height() / imageData->imageSize().height());

        loadOdfClipContour(element, context, scaleFactor);
        // this is needed so that the image is already normalized when calling waitUntilReady e.g. by cstester
        m_clippingRect.normalize(imageData->imageSize());

        return true;
    }
    return false;
}
Пример #11
0
QString PictureShape::saveStyle(KoGenStyle& style, KoShapeSavingContext& context) const
{
    if(transparency() > 0.0) {
        style.addProperty("draw:image-opacity", QString("%1%").arg((1.0 - transparency()) * 100.0));
    }

    // this attribute is need to work around a bug in LO 3.4 to make it recognice us as an
    // image and not just any shape. But we shouldn't produce illegal odf so: only for testing!
    // style.addAttribute("style:parent-style-name", "dummy");

    // Mirroring
    if (m_mirrorMode != MirrorNone) {
        QString mode;

        if (m_mirrorMode & MirrorHorizontal)
            mode = "horizontal";
        else if (m_mirrorMode & MirrorHorizontalOnEven)
            mode = "horizontal-on-even";
        else if (m_mirrorMode & MirrorHorizontalOnOdd)
            mode = "horizontal-on-odd";

        if (m_mirrorMode & MirrorVertical) {
            if (!mode.isEmpty())
                mode += ' ';
            mode += "vertical";
        }

        style.addProperty("style:mirror", mode);
    }

    switch(m_colorMode)
    {
    case Standard:
        style.addProperty("draw:color-mode", "standard");
        break;
    case Greyscale:
        style.addProperty("draw:color-mode", "greyscale");
        break;
    case Watermark:
        style.addProperty("draw:color-mode", "watermark");
        break;
    case Mono:
        style.addProperty("draw:color-mode", "mono");
        break;
    }

    KoImageData *imageData = qobject_cast<KoImageData*>(userData());

    if (imageData != 0) {
        QSizeF imageSize = imageData->imageSize();
        ClippingRect rect = m_clippingRect;

        rect.normalize(imageSize);
        rect.bottom = 1.0 - rect.bottom;
        rect.right = 1.0 - rect.right;

        if (!qFuzzyCompare(rect.left + rect.right + rect.top + rect.bottom, qreal(0))) {
            style.addProperty("fo:clip", QString("rect(%1pt, %2pt, %3pt, %4pt)")
                .arg(rect.top * imageSize.height())
                .arg(rect.right * imageSize.width())
                .arg(rect.bottom * imageSize.height())
                .arg(rect.left * imageSize.width())
            );
        }
    }

    return KoTosContainer::saveStyle(style, context);
}
Пример #12
0
QBrush Surface::loadOdfPatternStyle(const KoStyleStack &styleStack, 
                                    KoOdfLoadingContext &context, const QSizeF &size)
{
    QString styleName = styleStack.property(KoXmlNS::draw, "fill-image-name");

    KoXmlElement* e = context.stylesReader().drawStyles("fill-image")[styleName];
    if (! e)
        return QBrush();

    const QString href = e->attributeNS(KoXmlNS::xlink, "href", QString());

    if (href.isEmpty())
        return QBrush();

    QString strExtension;
    const int result = href.lastIndexOf(".");
    if (result >= 0) {
        strExtension = href.mid(result + 1); // As we are using KoPicture, the extension should be without the dot.
    }
    QString filename(href);

    KoImageData data;
    data.setImage(href, context.store());
    if (data.errorCode() != KoImageData::Success)
        return QBrush();

    // read the pattern repeat style
    QString style = styleStack.property(KoXmlNS::style, "repeat");
    kDebug(35001) << "pattern style =" << style;

    QSize imageSize = data.image().size();

    if (style == "stretch") {
        imageSize = size.toSize();
    } else {
        // optional attributes which can override original image size
        if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-height") && styleStack.hasProperty(KoXmlNS::draw, "fill-image-width")) {
            QString height = styleStack.property(KoXmlNS::draw, "fill-image-height");
            qreal newHeight = 0.0;
            if (height.endsWith('%'))
                newHeight = 0.01 * height.remove('%').toDouble() * imageSize.height();
            else
                newHeight = KoUnit::parseValue(height);
            QString width = styleStack.property(KoXmlNS::draw, "fill-image-width");
            qreal newWidth = 0.0;
            if (width.endsWith('%'))
                newWidth = 0.01 * width.remove('%').toDouble() * imageSize.width();
            else
                newWidth = KoUnit::parseValue(width);
            if (newHeight > 0.0)
                imageSize.setHeight(static_cast<int>(newHeight));
            if (newWidth > 0.0)
                imageSize.setWidth(static_cast<int>(newWidth));
        }
    }

    kDebug(35001) << "shape size =" << size;
    kDebug(35001) << "original image size =" << data.image().size();
    kDebug(35001) << "resulting image size =" << imageSize;

    QBrush resultBrush(QPixmap::fromImage(data.image()).scaled(imageSize));

    if (style == "repeat") {
        QTransform matrix;
        if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-ref-point")) {
            // align pattern to the given size
            QString align = styleStack.property(KoXmlNS::draw, "fill-image-ref-point");
            kDebug(35001) << "pattern align =" << align;
            if (align == "top-left")
                matrix.translate(0, 0);
            else if (align == "top")
                matrix.translate(0.5*size.width(), 0);
            else if (align == "top-right")
                matrix.translate(size.width(), 0);
            else if (align == "left")
                matrix.translate(0, 0.5*size.height());
            else if (align == "center")
                matrix.translate(0.5*size.width(), 0.5*size.height());
            else if (align == "right")
                matrix.translate(size.width(), 0.5*size.height());
            else if (align == "bottom-left")
                matrix.translate(0, size.height());
            else if (align == "bottom")
                matrix.translate(0.5*size.width(), size.height());
            else if (align == "bottom-right")
                matrix.translate(size.width(), size.height());
        }
        if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-ref-point-x")) {
            QString pointX = styleStack.property(KoXmlNS::draw, "fill-image-ref-point-x");
            matrix.translate(0.01 * pointX.remove('%').toDouble() * imageSize.width(), 0);
        }
        if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-ref-point-y")) {
            QString pointY = styleStack.property(KoXmlNS::draw, "fill-image-ref-point-y");
            matrix.translate(0, 0.01 * pointY.remove('%').toDouble() * imageSize.height());
        }
        resultBrush.setTransform(matrix);
    }

    return resultBrush;
}