File indexing completed on 2024-05-19 04:44:32

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk)
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012  * Lesser General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Lesser General Public
0015  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #include "KReportItemImage.h"
0019 #include "KReportUtils.h"
0020 #include "KReportRenderObjects.h"
0021 #include "kreportplugin_debug.h"
0022 
0023 #include <KPropertyListData>
0024 #include <KPropertySet>
0025 
0026 #include <QBuffer>
0027 #include <QDomNodeList>
0028 
0029 
0030 KReportItemImage::KReportItemImage()
0031 {
0032     createProperties();
0033 }
0034 
0035 KReportItemImage::KReportItemImage(const QDomNode & element)
0036     : KReportItemImage()
0037 {
0038     nameProperty()->setValue(KReportUtils::readNameAttribute(element.toElement()));
0039     setItemDataSource(element.toElement().attribute(QLatin1String("report:item-data-source")));
0040     m_resizeMode->setValue(element.toElement().attribute(QLatin1String("report:resize-mode"), QLatin1String("stretch")));
0041     setZ(element.toElement().attribute(QLatin1String("report:z-index")).toDouble());
0042 
0043     parseReportRect(element.toElement());
0044 
0045     QDomNodeList nl = element.childNodes();
0046     QString n;
0047     QDomNode node;
0048     for (int i = 0; i < nl.count(); i++) {
0049         node = nl.item(i);
0050         n = node.nodeName();
0051 
0052         if (n == QLatin1String("report:inline-image-data")) {
0053 
0054             setInlineImageData(node.firstChild().nodeValue().toLatin1());
0055         } else {
0056             kreportpluginWarning() << "while parsing image element encountered unknown element: " << n;
0057         }
0058     }
0059 }
0060 
0061 KReportItemImage::~KReportItemImage()
0062 {
0063 }
0064 
0065 bool KReportItemImage::isInline() const
0066 {
0067     return !(inlineImageData().isEmpty());
0068 }
0069 
0070 QByteArray KReportItemImage::inlineImageData() const
0071 {
0072     QPixmap pixmap = m_staticImage->value().value<QPixmap>();
0073     QByteArray ba;
0074     QBuffer buffer(&ba);
0075     buffer.open(QIODevice::ReadWrite);
0076     pixmap.save(&buffer, "PNG");   // writes pixmap into ba in PNG format,
0077     //! @todo should I remember the format used, or save as PNG as its lossless?
0078 
0079     return buffer.buffer().toBase64();
0080 }
0081 
0082 void KReportItemImage::setInlineImageData(const QByteArray &dat, const QString &fn)
0083 {
0084     if (!fn.isEmpty()) {
0085         QPixmap pix(fn);
0086         if (!pix.isNull())
0087             m_staticImage->setValue(pix);
0088         else {
0089             QPixmap blank(1, 1);
0090             blank.fill();
0091             m_staticImage->setValue(blank);
0092         }
0093     } else {
0094         const QByteArray binaryStream(QByteArray::fromBase64(dat));
0095         const QPixmap pix(QPixmap::fromImage(QImage::fromData(binaryStream), Qt::ColorOnly));
0096         m_staticImage->setValue(pix);
0097     }
0098 
0099 }
0100 
0101 QString KReportItemImage::mode() const
0102 {
0103     return m_resizeMode->value().toString();
0104 }
0105 
0106 void KReportItemImage::setMode(const QString &m)
0107 {
0108     if (mode() != m) {
0109         m_resizeMode->setValue(m);
0110     }
0111 }
0112 
0113 void KReportItemImage::createProperties()
0114 {
0115     createDataSourceProperty();
0116 
0117     KPropertyListData *listData = new KPropertyListData(
0118         { QLatin1String("clip"), QLatin1String("stretch") },
0119         QVariantList{ tr("Clip"), tr("Stretch") });
0120     m_resizeMode = new KProperty("resize-mode", listData, QLatin1String("clip"), tr("Resize Mode"));
0121     m_staticImage = new KProperty("static-image", QPixmap(), tr("Value"), tr("Value used if not bound to a field"));
0122 
0123     propertySet()->addProperty(m_resizeMode);
0124     propertySet()->addProperty(m_staticImage);
0125 }
0126 
0127 QString KReportItemImage::typeName() const
0128 {
0129     return QLatin1String("image");
0130 }
0131 
0132 int KReportItemImage::renderSimpleData(OROPage *page, OROSection *section, const QPointF &offset,
0133                                         const QVariant &data, KReportScriptHandler *script)
0134 {
0135     Q_UNUSED(script)
0136 
0137     QByteArray uudata;
0138     QByteArray imgdata;
0139     if (!isInline()) {
0140         imgdata = data.toByteArray();
0141     } else {
0142         uudata = inlineImageData();
0143         imgdata = QByteArray::fromBase64(uudata);
0144     }
0145 
0146     QImage img;
0147     img.loadFromData(imgdata);
0148     OROImage * id = new OROImage();
0149     id->setImage(img);
0150     if (mode().toLower() == QLatin1String("stretch")) {
0151         id->setScaled(true);
0152         id->setAspectRatioMode(Qt::KeepAspectRatio);
0153         id->setTransformationMode(Qt::SmoothTransformation);
0154     }
0155 
0156     id->setPosition(scenePosition(position()) + offset);
0157     id->setSize(sceneSize(size()));
0158     if (page) {
0159         page->insertPrimitive(id);
0160     }
0161 
0162     if (section) {
0163         OROImage *i2 = dynamic_cast<OROImage*>(id->clone());
0164         if (i2) {
0165             i2->setPosition(scenePosition(position()));
0166             section->addPrimitive(i2);
0167         }
0168     }
0169 
0170     if (!page) {
0171         delete id;
0172     }
0173 
0174     return 0; //Item doesn't stretch the section height
0175 }
0176 
0177