File indexing completed on 2025-01-19 03:39:53
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"