Mercurial > clickerconvert
comparison src/xlsx/xlsxrichstring.cpp @ 1:93d3106bb9a4
Add qt xlsx library
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Tue, 22 Mar 2016 10:38:08 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:49cd5cc0b072 | 1:93d3106bb9a4 |
---|---|
1 /**************************************************************************** | |
2 ** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me> | |
3 ** All right reserved. | |
4 ** | |
5 ** Permission is hereby granted, free of charge, to any person obtaining | |
6 ** a copy of this software and associated documentation files (the | |
7 ** "Software"), to deal in the Software without restriction, including | |
8 ** without limitation the rights to use, copy, modify, merge, publish, | |
9 ** distribute, sublicense, and/or sell copies of the Software, and to | |
10 ** permit persons to whom the Software is furnished to do so, subject to | |
11 ** the following conditions: | |
12 ** | |
13 ** The above copyright notice and this permission notice shall be | |
14 ** included in all copies or substantial portions of the Software. | |
15 ** | |
16 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
18 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
19 ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
20 ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
21 ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
22 ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
23 ** | |
24 ****************************************************************************/ | |
25 #include "xlsxrichstring.h" | |
26 #include "xlsxrichstring_p.h" | |
27 #include "xlsxformat_p.h" | |
28 #include <QDebug> | |
29 #include <QTextDocument> | |
30 #include <QTextFragment> | |
31 | |
32 QT_BEGIN_NAMESPACE_XLSX | |
33 | |
34 RichStringPrivate::RichStringPrivate() | |
35 :_dirty(true) | |
36 { | |
37 | |
38 } | |
39 | |
40 RichStringPrivate::RichStringPrivate(const RichStringPrivate &other) | |
41 :QSharedData(other), fragmentTexts(other.fragmentTexts) | |
42 ,fragmentFormats(other.fragmentFormats) | |
43 , _idKey(other.idKey()), _dirty(other._dirty) | |
44 { | |
45 | |
46 } | |
47 | |
48 RichStringPrivate::~RichStringPrivate() | |
49 { | |
50 | |
51 } | |
52 | |
53 /*! | |
54 \class RichString | |
55 \inmodule QtXlsx | |
56 \brief This class add support for the rich text string of the cell. | |
57 */ | |
58 | |
59 /*! | |
60 Constructs a null string. | |
61 */ | |
62 RichString::RichString() | |
63 :d(new RichStringPrivate) | |
64 { | |
65 } | |
66 | |
67 /*! | |
68 Constructs a plain string with the given \a text. | |
69 */ | |
70 RichString::RichString(const QString text) | |
71 :d(new RichStringPrivate) | |
72 { | |
73 addFragment(text, Format()); | |
74 } | |
75 | |
76 /*! | |
77 Constructs a copy of \a other. | |
78 */ | |
79 RichString::RichString(const RichString &other) | |
80 :d(other.d) | |
81 { | |
82 | |
83 } | |
84 | |
85 /*! | |
86 Destructs the string. | |
87 */ | |
88 RichString::~RichString() | |
89 { | |
90 | |
91 } | |
92 | |
93 /*! | |
94 Assigns \a other to this string and returns a reference to this string | |
95 */ | |
96 RichString &RichString::operator =(const RichString &other) | |
97 { | |
98 this->d = other.d; | |
99 return *this; | |
100 } | |
101 | |
102 /*! | |
103 Returns the rich string as a QVariant | |
104 */ | |
105 RichString::operator QVariant() const | |
106 { | |
107 return QVariant(qMetaTypeId<RichString>(), this); | |
108 } | |
109 | |
110 /*! | |
111 Returns true if this is rich text string. | |
112 */ | |
113 bool RichString::isRichString() const | |
114 { | |
115 if (fragmentCount() > 1) //Is this enough?? | |
116 return true; | |
117 return false; | |
118 } | |
119 | |
120 /*! | |
121 Returns true is this is an Null string. | |
122 */ | |
123 bool RichString::isNull() const | |
124 { | |
125 return d->fragmentTexts.size() == 0; | |
126 } | |
127 | |
128 /*! | |
129 Returns true is this is an empty string. | |
130 */ | |
131 bool RichString::isEmtpy() const | |
132 { | |
133 foreach (const QString str, d->fragmentTexts) { | |
134 if (!str.isEmpty()) | |
135 return false; | |
136 } | |
137 | |
138 return true; | |
139 } | |
140 | |
141 /*! | |
142 Converts to plain text string. | |
143 */ | |
144 QString RichString::toPlainString() const | |
145 { | |
146 if (isEmtpy()) | |
147 return QString(); | |
148 if (d->fragmentTexts.size() == 1) | |
149 return d->fragmentTexts[0]; | |
150 | |
151 return d->fragmentTexts.join(QString()); | |
152 } | |
153 | |
154 /*! | |
155 Converts to html string | |
156 */ | |
157 QString RichString::toHtml() const | |
158 { | |
159 //: Todo | |
160 return QString(); | |
161 } | |
162 | |
163 /*! | |
164 Replaces the entire contents of the document | |
165 with the given HTML-formatted text in the \a text string | |
166 */ | |
167 void RichString::setHtml(const QString &text) | |
168 { | |
169 QTextDocument doc; | |
170 doc.setHtml(text); | |
171 QTextBlock block = doc.firstBlock(); | |
172 QTextBlock::iterator it; | |
173 for (it = block.begin(); !(it.atEnd()); ++it) { | |
174 QTextFragment textFragment = it.fragment(); | |
175 if (textFragment.isValid()) { | |
176 Format fmt; | |
177 fmt.setFont(textFragment.charFormat().font()); | |
178 fmt.setFontColor(textFragment.charFormat().foreground().color()); | |
179 addFragment(textFragment.text(), fmt); | |
180 } | |
181 } | |
182 } | |
183 | |
184 /*! | |
185 Returns fragment count. | |
186 */ | |
187 int RichString::fragmentCount() const | |
188 { | |
189 return d->fragmentTexts.size(); | |
190 } | |
191 | |
192 /*! | |
193 Appends a fragment with the given \a text and \a format. | |
194 */ | |
195 void RichString::addFragment(const QString &text, const Format &format) | |
196 { | |
197 d->fragmentTexts.append(text); | |
198 d->fragmentFormats.append(format); | |
199 d->_dirty = true; | |
200 } | |
201 | |
202 /*! | |
203 Returns fragment text at the position \a index. | |
204 */ | |
205 QString RichString::fragmentText(int index) const | |
206 { | |
207 if (index < 0 || index >= fragmentCount()) | |
208 return QString(); | |
209 | |
210 return d->fragmentTexts[index]; | |
211 } | |
212 | |
213 /*! | |
214 Returns fragment format at the position \a index. | |
215 */ | |
216 Format RichString::fragmentFormat(int index) const | |
217 { | |
218 if (index < 0 || index >= fragmentCount()) | |
219 return Format(); | |
220 | |
221 return d->fragmentFormats[index]; | |
222 } | |
223 | |
224 /*! | |
225 * \internal | |
226 */ | |
227 QByteArray RichStringPrivate::idKey() const | |
228 { | |
229 if (_dirty) { | |
230 RichStringPrivate *rs = const_cast<RichStringPrivate *>(this); | |
231 QByteArray bytes; | |
232 if (fragmentTexts.size() == 1) { | |
233 bytes = fragmentTexts[0].toUtf8(); | |
234 } else { | |
235 //Generate a hash value base on QByteArray ? | |
236 bytes.append("@@QtXlsxRichString="); | |
237 for (int i=0; i<fragmentTexts.size(); ++i) { | |
238 bytes.append("@Text"); | |
239 bytes.append(fragmentTexts[i].toUtf8()); | |
240 bytes.append("@Format"); | |
241 if (fragmentFormats[i].hasFontData()) | |
242 bytes.append(fragmentFormats[i].fontKey()); | |
243 } | |
244 } | |
245 rs->_idKey = bytes; | |
246 rs->_dirty = false; | |
247 } | |
248 | |
249 return _idKey; | |
250 } | |
251 | |
252 /*! | |
253 Returns true if this string \a rs1 is equal to string \a rs2; | |
254 otherwise returns false. | |
255 */ | |
256 bool operator==(const RichString &rs1, const RichString &rs2) | |
257 { | |
258 if (rs1.fragmentCount() != rs2.fragmentCount()) | |
259 return false; | |
260 | |
261 return rs1.d->idKey() == rs2.d->idKey(); | |
262 } | |
263 | |
264 /*! | |
265 Returns true if this string \a rs1 is not equal to string \a rs2; | |
266 otherwise returns false. | |
267 */ | |
268 bool operator!=(const RichString &rs1, const RichString &rs2) | |
269 { | |
270 if (rs1.fragmentCount() != rs2.fragmentCount()) | |
271 return true; | |
272 | |
273 return rs1.d->idKey() != rs2.d->idKey(); | |
274 } | |
275 | |
276 /*! | |
277 * \internal | |
278 */ | |
279 bool operator<(const RichString &rs1, const RichString &rs2) | |
280 { | |
281 return rs1.d->idKey() < rs2.d->idKey(); | |
282 } | |
283 | |
284 /*! | |
285 \overload | |
286 Returns true if this string \a rs1 is equal to string \a rs2; | |
287 otherwise returns false. | |
288 */ | |
289 bool operator ==(const RichString &rs1, const QString &rs2) | |
290 { | |
291 if (rs1.fragmentCount() == 1 && rs1.fragmentText(0) == rs2) //format == 0 | |
292 return true; | |
293 | |
294 return false; | |
295 } | |
296 | |
297 /*! | |
298 \overload | |
299 Returns true if this string \a rs1 is not equal to string \a rs2; | |
300 otherwise returns false. | |
301 */ | |
302 bool operator !=(const RichString &rs1, const QString &rs2) | |
303 { | |
304 if (rs1.fragmentCount() == 1 && rs1.fragmentText(0) == rs2) //format == 0 | |
305 return false; | |
306 | |
307 return true; | |
308 } | |
309 | |
310 /*! | |
311 \overload | |
312 Returns true if this string \a rs1 is equal to string \a rs2; | |
313 otherwise returns false. | |
314 */ | |
315 bool operator ==(const QString &rs1, const RichString &rs2) | |
316 { | |
317 return rs2 == rs1; | |
318 } | |
319 | |
320 /*! | |
321 \overload | |
322 Returns true if this string \a rs1 is not equal to string \a rs2; | |
323 otherwise returns false. | |
324 */ | |
325 bool operator !=(const QString &rs1, const RichString &rs2) | |
326 { | |
327 return rs2 != rs1; | |
328 } | |
329 | |
330 uint qHash(const RichString &rs, uint seed) Q_DECL_NOTHROW | |
331 { | |
332 return qHash(rs.d->idKey(), seed); | |
333 } | |
334 | |
335 #ifndef QT_NO_DEBUG_STREAM | |
336 QDebug operator<<(QDebug dbg, const RichString &rs) | |
337 { | |
338 dbg.nospace() << "QXlsx::RichString(" << rs.d->fragmentTexts << ")"; | |
339 return dbg.space(); | |
340 } | |
341 #endif | |
342 | |
343 QT_END_NAMESPACE_XLSX |