1/*
2 This file is part of libkabc.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "picture.h"
22
23#include <QtCore/QBuffer>
24#include <QtCore/QSharedData>
25
26namespace KABC {
27
28class PicturePrivate : public QSharedData
29{
30 public:
31 PicturePrivate()
32 : mIntern( false )
33 {
34 }
35
36 PicturePrivate( const PicturePrivate &other )
37 : QSharedData( other )
38 {
39 mUrl = other.mUrl;
40 mType = other.mType;
41 mData = other.mData;
42 mIntern = other.mIntern;
43 }
44
45 QString mUrl;
46 QString mType;
47 mutable QImage mData;
48 mutable QByteArray mRawData;
49
50 bool mIntern;
51};
52
53}
54
55Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<KABC::PicturePrivate>, s_sharedEmpty, (new KABC::PicturePrivate))
56
57using namespace KABC;
58
59Picture::Picture()
60 : d( *s_sharedEmpty() )
61{
62}
63
64Picture::Picture( const QString &url )
65 : d( new PicturePrivate )
66{
67 d->mUrl = url;
68}
69
70Picture::Picture( const QImage &data )
71 : d( new PicturePrivate )
72{
73 setData( data );
74}
75
76Picture::Picture( const Picture &other )
77 : d( other.d )
78{
79}
80
81Picture::~Picture()
82{
83}
84
85Picture &Picture::operator=( const Picture &other )
86{
87 if ( this != &other ) {
88 d = other.d;
89 }
90
91 return *this;
92}
93
94bool Picture::operator==( const Picture &p ) const
95{
96 if ( d->mIntern != p.d->mIntern ) {
97 return false;
98 }
99
100 if ( d->mType != p.d->mType ) {
101 return false;
102 }
103
104 if ( d->mIntern ) {
105 if ( !d->mData.isNull() && !p.d->mData.isNull() ) {
106 if ( d->mData != p.d->mData ) {
107 return false;
108 }
109 } else if ( !d->mRawData.isEmpty() && !p.d->mRawData.isEmpty() ) {
110 if ( d->mRawData != p.d->mRawData ) {
111 return false;
112 }
113 } else if ( ( !d->mData.isNull() || !d->mRawData.isEmpty() ) &&
114 ( !p.d->mData.isNull() || !p.d->mRawData.isEmpty() ) ) {
115 if ( data() != p.data() ) {
116 return false;
117 }
118 } else {
119 // if one picture is empty and the other is not
120 return false;
121 }
122 } else {
123 if ( d->mUrl != p.d->mUrl ) {
124 return false;
125 }
126 }
127
128 return true;
129}
130
131bool Picture::operator!=( const Picture &p ) const
132{
133 return !( p == *this );
134}
135
136bool Picture::isEmpty() const
137{
138 return
139 ( ( d->mIntern == false && d->mUrl.isEmpty() ) ||
140 ( d->mIntern == true && d->mData.isNull() && d->mRawData.isEmpty() ) );
141}
142
143void Picture::setUrl( const QString &url )
144{
145 d->mUrl = url;
146 d->mType.clear();
147 d->mIntern = false;
148}
149
150void Picture::setUrl( const QString &url, const QString &type )
151{
152 d->mUrl = url;
153 d->mType = type;
154 d->mIntern = false;
155}
156
157void Picture::setData( const QImage &data )
158{
159 d->mRawData.clear();
160 d->mData = data;
161 d->mIntern = true;
162
163 // set the type, the raw data will have when accessed through Picture::rawData()
164 if ( !d->mData.hasAlphaChannel() ) {
165 d->mType = QLatin1String( "jpeg" );
166 } else {
167 d->mType = QLatin1String( "png" );
168 }
169}
170
171void Picture::setRawData( const QByteArray &rawData, const QString &type )
172{
173 d->mRawData = rawData;
174 d->mType = type;
175 d->mData = QImage();
176 d->mIntern = true;
177}
178
179void Picture::setType( const QString &type )
180{
181 d->mType = type;
182}
183
184bool Picture::isIntern() const
185{
186 return d->mIntern;
187}
188
189QString Picture::url() const
190{
191 return d->mUrl;
192}
193
194QImage Picture::data() const
195{
196 if ( d->mData.isNull() && !d->mRawData.isEmpty() ) {
197 d->mData.loadFromData( d->mRawData );
198 }
199
200 return d->mData;
201}
202
203QByteArray Picture::rawData() const
204{
205 if ( d->mRawData.isEmpty() && !d->mData.isNull() ) {
206 QBuffer buffer( &d->mRawData );
207 buffer.open( QIODevice::WriteOnly );
208
209 // d->mType was already set accordingly by Picture::setData()
210 d->mData.save( &buffer, d->mType.toUpper().toLatin1().data() );
211 }
212
213 return d->mRawData;
214}
215
216QString Picture::type() const
217{
218 return d->mType;
219}
220
221QString Picture::toString() const
222{
223 QString str;
224
225 str += QLatin1String( "Picture {\n" );
226 str += QString::fromLatin1( " Type: %1\n" ).arg( d->mType );
227 str += QString::fromLatin1( " IsIntern: %1\n" ).
228 arg( d->mIntern ? QLatin1String( "true" ) : QLatin1String( "false" ) );
229 if ( d->mIntern ) {
230 str += QString::fromLatin1( " Data: %1\n" ).arg( QString::fromLatin1( rawData().toBase64() ) );
231 } else {
232 str += QString::fromLatin1( " Url: %1\n" ).arg( d->mUrl );
233 }
234 str += QLatin1String( "}\n" );
235
236 return str;
237}
238
239QDataStream &KABC::operator<<( QDataStream &s, const Picture &picture )
240{
241 return s << picture.d->mIntern << picture.d->mUrl << picture.d->mType << picture.data();
242}
243
244QDataStream &KABC::operator>>( QDataStream &s, Picture &picture )
245{
246 s >> picture.d->mIntern >> picture.d->mUrl >> picture.d->mType >> picture.d->mData;
247
248 return s;
249}
250