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 | |
26 | namespace KABC { |
27 | |
28 | class 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 | |
55 | Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<KABC::PicturePrivate>, s_sharedEmpty, (new KABC::PicturePrivate)) |
56 | |
57 | using namespace KABC; |
58 | |
59 | Picture::Picture() |
60 | : d( *s_sharedEmpty() ) |
61 | { |
62 | } |
63 | |
64 | Picture::Picture( const QString &url ) |
65 | : d( new PicturePrivate ) |
66 | { |
67 | d->mUrl = url; |
68 | } |
69 | |
70 | Picture::Picture( const QImage &data ) |
71 | : d( new PicturePrivate ) |
72 | { |
73 | setData( data ); |
74 | } |
75 | |
76 | Picture::Picture( const Picture &other ) |
77 | : d( other.d ) |
78 | { |
79 | } |
80 | |
81 | Picture::~Picture() |
82 | { |
83 | } |
84 | |
85 | Picture &Picture::operator=( const Picture &other ) |
86 | { |
87 | if ( this != &other ) { |
88 | d = other.d; |
89 | } |
90 | |
91 | return *this; |
92 | } |
93 | |
94 | bool 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 | |
131 | bool Picture::operator!=( const Picture &p ) const |
132 | { |
133 | return !( p == *this ); |
134 | } |
135 | |
136 | bool 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 | |
143 | void Picture::setUrl( const QString &url ) |
144 | { |
145 | d->mUrl = url; |
146 | d->mType.clear(); |
147 | d->mIntern = false; |
148 | } |
149 | |
150 | void Picture::setUrl( const QString &url, const QString &type ) |
151 | { |
152 | d->mUrl = url; |
153 | d->mType = type; |
154 | d->mIntern = false; |
155 | } |
156 | |
157 | void 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 | |
171 | void 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 | |
179 | void Picture::setType( const QString &type ) |
180 | { |
181 | d->mType = type; |
182 | } |
183 | |
184 | bool Picture::isIntern() const |
185 | { |
186 | return d->mIntern; |
187 | } |
188 | |
189 | QString Picture::url() const |
190 | { |
191 | return d->mUrl; |
192 | } |
193 | |
194 | QImage 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 | |
203 | QByteArray 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 | |
216 | QString Picture::type() const |
217 | { |
218 | return d->mType; |
219 | } |
220 | |
221 | QString 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 | |
239 | QDataStream &KABC::operator<<( QDataStream &s, const Picture &picture ) |
240 | { |
241 | return s << picture.d->mIntern << picture.d->mUrl << picture.d->mType << picture.data(); |
242 | } |
243 | |
244 | QDataStream &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 | |