File indexing completed on 2024-04-21 03:53:34

0001 /*
0002     This file is part of the KContacts framework.
0003     SPDX-FileCopyrightText: 2002 Tobias Koenig <tokoe@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "picture.h"
0009 
0010 #include <QBuffer>
0011 #include <QSharedData>
0012 
0013 
0014 namespace KContacts
0015 {
0016 class PicturePrivate : public QSharedData
0017 {
0018 public:
0019     PicturePrivate()
0020         : mIntern(false)
0021     {
0022     }
0023 
0024     PicturePrivate(const PicturePrivate &other)
0025         : QSharedData(other)
0026         , mUrl(other.mUrl)
0027         , mType(other.mType)
0028         , mData(other.mData)
0029         , mIntern(other.mIntern)
0030     {
0031     }
0032 
0033     QString mUrl;
0034     QString mType;
0035     mutable QImage mData;
0036     mutable QByteArray mRawData;
0037 
0038     bool mIntern;
0039 };
0040 }
0041 
0042 Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<KContacts::PicturePrivate>, s_sharedEmpty, (new KContacts::PicturePrivate))
0043 
0044 using namespace KContacts;
0045 
0046 Picture::Picture()
0047     : d(*s_sharedEmpty())
0048 {
0049 }
0050 
0051 Picture::Picture(const QString &url)
0052     : d(new PicturePrivate)
0053 {
0054     d->mUrl = url;
0055 }
0056 
0057 Picture::Picture(const QImage &data)
0058     : d(new PicturePrivate)
0059 {
0060     setData(data);
0061 }
0062 
0063 Picture::Picture(const Picture &other)
0064     : d(other.d)
0065 {
0066 }
0067 
0068 Picture::~Picture()
0069 {
0070 }
0071 
0072 Picture &Picture::operator=(const Picture &other)
0073 {
0074     if (this != &other) {
0075         d = other.d;
0076     }
0077 
0078     return *this;
0079 }
0080 
0081 bool Picture::operator==(const Picture &p) const
0082 {
0083     if (d->mIntern != p.d->mIntern) {
0084         return false;
0085     }
0086 
0087     if (d->mType != p.d->mType) {
0088         return false;
0089     }
0090 
0091     if (d->mIntern) {
0092         if (!d->mData.isNull() && !p.d->mData.isNull()) {
0093             if (d->mData != p.d->mData) {
0094                 return false;
0095             }
0096         } else if (!d->mRawData.isEmpty() && !p.d->mRawData.isEmpty()) {
0097             if (d->mRawData != p.d->mRawData) {
0098                 return false;
0099             }
0100         } else if ((!d->mData.isNull() || !d->mRawData.isEmpty()) //
0101                    && (!p.d->mData.isNull() || !p.d->mRawData.isEmpty())) {
0102             if (data() != p.data()) {
0103                 return false;
0104             }
0105         } else {
0106             // if one picture is empty and the other is not
0107             return false;
0108         }
0109     } else {
0110         if (d->mUrl != p.d->mUrl) {
0111             return false;
0112         }
0113     }
0114 
0115     return true;
0116 }
0117 
0118 bool Picture::operator!=(const Picture &p) const
0119 {
0120     return !(p == *this);
0121 }
0122 
0123 bool Picture::isEmpty() const
0124 {
0125     return (!d->mIntern && d->mUrl.isEmpty()) //
0126         || (d->mIntern && d->mData.isNull() && d->mRawData.isEmpty());
0127 }
0128 
0129 void Picture::setUrl(const QString &url)
0130 {
0131     d->mUrl = url;
0132     d->mType.clear();
0133     d->mIntern = false;
0134 }
0135 
0136 void Picture::setUrl(const QString &url, const QString &type)
0137 {
0138     d->mUrl = url;
0139     d->mType = type;
0140     d->mIntern = false;
0141 }
0142 
0143 void Picture::setData(const QImage &data)
0144 {
0145     d->mRawData.clear();
0146     d->mData = data;
0147     d->mIntern = true;
0148 
0149     // set the type, the raw data will have when accessed through Picture::rawData()
0150     if (!d->mData.hasAlphaChannel()) {
0151         d->mType = QStringLiteral("jpeg");
0152     } else {
0153         d->mType = QStringLiteral("png");
0154     }
0155 }
0156 
0157 void Picture::setRawData(const QByteArray &rawData, const QString &type)
0158 {
0159     d->mRawData = rawData;
0160     d->mType = type;
0161     d->mData = QImage();
0162     d->mIntern = true;
0163 }
0164 
0165 bool Picture::isIntern() const
0166 {
0167     return d->mIntern;
0168 }
0169 
0170 QString Picture::url() const
0171 {
0172     return d->mUrl;
0173 }
0174 
0175 QImage Picture::data() const
0176 {
0177     if (d->mData.isNull() && !d->mRawData.isEmpty()) {
0178         d->mData.loadFromData(d->mRawData);
0179     }
0180 
0181     return d->mData;
0182 }
0183 
0184 QByteArray Picture::rawData() const
0185 {
0186     if (d->mRawData.isEmpty() && !d->mData.isNull()) {
0187         QBuffer buffer(&d->mRawData);
0188         buffer.open(QIODevice::WriteOnly);
0189 
0190         // d->mType was already set accordingly by Picture::setData()
0191         d->mData.save(&buffer, d->mType.toUpper().toLatin1().data());
0192     }
0193 
0194     return d->mRawData;
0195 }
0196 
0197 QString Picture::type() const
0198 {
0199     return d->mType;
0200 }
0201 
0202 QString Picture::toString() const
0203 {
0204     QString str = QLatin1String("Picture {\n");
0205     str += QStringLiteral("  Type: %1\n").arg(d->mType);
0206     str += QStringLiteral("  IsIntern: %1\n").arg(d->mIntern ? QStringLiteral("true") : QStringLiteral("false"));
0207     if (d->mIntern) {
0208         str += QStringLiteral("  Data: %1\n").arg(QString::fromLatin1(rawData().toBase64()));
0209     } else {
0210         str += QStringLiteral("  Url: %1\n").arg(d->mUrl);
0211     }
0212     str += QLatin1String("}\n");
0213 
0214     return str;
0215 }
0216 
0217 QDataStream &KContacts::operator<<(QDataStream &s, const Picture &picture)
0218 {
0219     return s << picture.d->mIntern << picture.d->mUrl << picture.d->mType << picture.data();
0220 }
0221 
0222 QDataStream &KContacts::operator>>(QDataStream &s, Picture &picture)
0223 {
0224     s >> picture.d->mIntern >> picture.d->mUrl >> picture.d->mType >> picture.d->mData;
0225 
0226     return s;
0227 }
0228 
0229 #include "moc_picture.cpp"