Mercurial > clickerconvert
comparison src/xlsx/xlsxstyles.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 "xlsxstyles_p.h" | |
26 #include "xlsxformat_p.h" | |
27 #include "xlsxutility_p.h" | |
28 #include "xlsxcolor_p.h" | |
29 #include <QXmlStreamWriter> | |
30 #include <QXmlStreamReader> | |
31 #include <QFile> | |
32 #include <QMap> | |
33 #include <QDataStream> | |
34 #include <QDebug> | |
35 #include <QBuffer> | |
36 | |
37 namespace QXlsx { | |
38 | |
39 /* | |
40 When loading from existing .xlsx file. we should create a clean styles object. | |
41 otherwise, default formats should be added. | |
42 | |
43 */ | |
44 Styles::Styles(CreateFlag flag) | |
45 : AbstractOOXmlFile(flag), m_nextCustomNumFmtId(176), m_isIndexedColorsDefault(true) | |
46 , m_emptyFormatAdded(false) | |
47 { | |
48 //!Fix me. Should the custom num fmt Id starts with 164 or 176 or others?? | |
49 | |
50 //!Fix me! Where should we put these register code? | |
51 if (QMetaType::type("XlsxColor") == QMetaType::UnknownType) { | |
52 qRegisterMetaType<XlsxColor>("XlsxColor"); | |
53 qRegisterMetaTypeStreamOperators<XlsxColor>("XlsxColor"); | |
54 #if QT_VERSION >= 0x050200 | |
55 QMetaType::registerDebugStreamOperator<XlsxColor>(); | |
56 #endif | |
57 } | |
58 | |
59 if (flag == F_NewFromScratch) { | |
60 //Add default Format | |
61 Format defaultFmt; | |
62 addXfFormat(defaultFmt); | |
63 | |
64 //Add another fill format | |
65 Format fillFmt; | |
66 fillFmt.setFillPattern(Format::PatternGray125); | |
67 m_fillsList.append(fillFmt); | |
68 m_fillsHash.insert(fillFmt.fillKey(), fillFmt); | |
69 } | |
70 } | |
71 | |
72 Styles::~Styles() | |
73 { | |
74 } | |
75 | |
76 Format Styles::xfFormat(int idx) const | |
77 { | |
78 if (idx <0 || idx >= m_xf_formatsList.size()) | |
79 return Format(); | |
80 | |
81 return m_xf_formatsList[idx]; | |
82 } | |
83 | |
84 Format Styles::dxfFormat(int idx) const | |
85 { | |
86 if (idx <0 || idx >= m_dxf_formatsList.size()) | |
87 return Format(); | |
88 | |
89 return m_dxf_formatsList[idx]; | |
90 } | |
91 | |
92 void Styles::fixNumFmt(const Format &format) | |
93 { | |
94 if (!format.hasNumFmtData()) | |
95 return; | |
96 | |
97 if (format.hasProperty(FormatPrivate::P_NumFmt_Id) | |
98 && !format.stringProperty(FormatPrivate::P_NumFmt_FormatCode).isEmpty()) { | |
99 return; | |
100 } | |
101 | |
102 if (m_builtinNumFmtsHash.isEmpty()) { | |
103 m_builtinNumFmtsHash.insert(QStringLiteral("General"), 0); | |
104 m_builtinNumFmtsHash.insert(QStringLiteral("0"), 1); | |
105 m_builtinNumFmtsHash.insert(QStringLiteral("0.00"), 2); | |
106 m_builtinNumFmtsHash.insert(QStringLiteral("#,##0"), 3); | |
107 m_builtinNumFmtsHash.insert(QStringLiteral("#,##0.00"), 4); | |
108 // m_builtinNumFmtsHash.insert(QStringLiteral("($#,##0_);($#,##0)"), 5); | |
109 // m_builtinNumFmtsHash.insert(QStringLiteral("($#,##0_);[Red]($#,##0)"), 6); | |
110 // m_builtinNumFmtsHash.insert(QStringLiteral("($#,##0.00_);($#,##0.00)"), 7); | |
111 // m_builtinNumFmtsHash.insert(QStringLiteral("($#,##0.00_);[Red]($#,##0.00)"), 8); | |
112 m_builtinNumFmtsHash.insert(QStringLiteral("0%"), 9); | |
113 m_builtinNumFmtsHash.insert(QStringLiteral("0.00%"), 10); | |
114 m_builtinNumFmtsHash.insert(QStringLiteral("0.00E+00"), 11); | |
115 m_builtinNumFmtsHash.insert(QStringLiteral("# ?/?"), 12); | |
116 m_builtinNumFmtsHash.insert(QStringLiteral("# ?\?/??"), 13);// Note: "??/" is a c++ trigraph, so escape one "?" | |
117 m_builtinNumFmtsHash.insert(QStringLiteral("m/d/yy"), 14); | |
118 m_builtinNumFmtsHash.insert(QStringLiteral("d-mmm-yy"), 15); | |
119 m_builtinNumFmtsHash.insert(QStringLiteral("d-mmm"), 16); | |
120 m_builtinNumFmtsHash.insert(QStringLiteral("mmm-yy"), 17); | |
121 m_builtinNumFmtsHash.insert(QStringLiteral("h:mm AM/PM"), 18); | |
122 m_builtinNumFmtsHash.insert(QStringLiteral("h:mm:ss AM/PM"), 19); | |
123 m_builtinNumFmtsHash.insert(QStringLiteral("h:mm"), 20); | |
124 m_builtinNumFmtsHash.insert(QStringLiteral("h:mm:ss"), 21); | |
125 m_builtinNumFmtsHash.insert(QStringLiteral("m/d/yy h:mm"), 22); | |
126 | |
127 m_builtinNumFmtsHash.insert(QStringLiteral("(#,##0_);(#,##0)"), 37); | |
128 m_builtinNumFmtsHash.insert(QStringLiteral("(#,##0_);[Red](#,##0)"), 38); | |
129 m_builtinNumFmtsHash.insert(QStringLiteral("(#,##0.00_);(#,##0.00)"), 39); | |
130 m_builtinNumFmtsHash.insert(QStringLiteral("(#,##0.00_);[Red](#,##0.00)"), 40); | |
131 // m_builtinNumFmtsHash.insert(QStringLiteral("_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(_)"), 41); | |
132 // m_builtinNumFmtsHash.insert(QStringLiteral("_($* #,##0_);_($* (#,##0);_($* \"-\"_);_(_)"), 42); | |
133 // m_builtinNumFmtsHash.insert(QStringLiteral("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(_)"), 43); | |
134 // m_builtinNumFmtsHash.insert(QStringLiteral("_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(_)"), 44); | |
135 m_builtinNumFmtsHash.insert(QStringLiteral("mm:ss"), 45); | |
136 m_builtinNumFmtsHash.insert(QStringLiteral("[h]:mm:ss"), 46); | |
137 m_builtinNumFmtsHash.insert(QStringLiteral("mm:ss.0"), 47); | |
138 m_builtinNumFmtsHash.insert(QStringLiteral("##0.0E+0"), 48); | |
139 m_builtinNumFmtsHash.insert(QStringLiteral("@"), 49); | |
140 } | |
141 | |
142 const QString str = format.numberFormat(); | |
143 if (!str.isEmpty()) { | |
144 //Assign proper number format index | |
145 if (m_builtinNumFmtsHash.contains(str)) { | |
146 const_cast<Format *>(&format)->fixNumberFormat(m_builtinNumFmtsHash[str], str); | |
147 } else if (m_customNumFmtsHash.contains(str)) { | |
148 const_cast<Format *>(&format)->fixNumberFormat(m_customNumFmtsHash[str]->formatIndex, str); | |
149 } else { | |
150 //Assign a new fmt Id. | |
151 const_cast<Format *>(&format)->fixNumberFormat(m_nextCustomNumFmtId, str); | |
152 | |
153 QSharedPointer<XlsxFormatNumberData> fmt(new XlsxFormatNumberData); | |
154 fmt->formatIndex = m_nextCustomNumFmtId; | |
155 fmt->formatString = str; | |
156 m_customNumFmtIdMap.insert(m_nextCustomNumFmtId, fmt); | |
157 m_customNumFmtsHash.insert(str, fmt); | |
158 | |
159 m_nextCustomNumFmtId += 1; | |
160 } | |
161 } else { | |
162 int id = format.numberFormatIndex(); | |
163 //Assign proper format code, this is needed by dxf format | |
164 if (m_customNumFmtIdMap.contains(id)) { | |
165 const_cast<Format *>(&format)->fixNumberFormat(id, m_customNumFmtIdMap[id]->formatString); | |
166 } else { | |
167 QHashIterator<QString, int> it(m_builtinNumFmtsHash); | |
168 bool find=false; | |
169 while (it.hasNext()) { | |
170 it.next(); | |
171 if (it.value() == id) { | |
172 const_cast<Format *>(&format)->fixNumberFormat(id, it.key()); | |
173 find = true; | |
174 break; | |
175 } | |
176 } | |
177 | |
178 if (!find) { | |
179 //Wrong numFmt | |
180 const_cast<Format *>(&format)->fixNumberFormat(id, QStringLiteral("General")); | |
181 } | |
182 } | |
183 } | |
184 } | |
185 | |
186 /* | |
187 Assign index to Font/Fill/Border and Format | |
188 | |
189 When \a force is true, add the format to the format list, even other format has | |
190 the same key have been in. | |
191 This is useful when reading existing .xlsx files which may contains duplicated formats. | |
192 */ | |
193 void Styles::addXfFormat(const Format &format, bool force) | |
194 { | |
195 if (format.isEmpty()) { | |
196 //Try do something for empty Format. | |
197 if (m_emptyFormatAdded && !force) | |
198 return; | |
199 m_emptyFormatAdded = true; | |
200 } | |
201 | |
202 //numFmt | |
203 if (format.hasNumFmtData() && !format.hasProperty(FormatPrivate::P_NumFmt_Id)) | |
204 fixNumFmt(format); | |
205 | |
206 //Font | |
207 if (format.hasFontData() && !format.fontIndexValid()) { | |
208 //Assign proper font index, if has font data. | |
209 if (!m_fontsHash.contains(format.fontKey())) | |
210 const_cast<Format *>(&format)->setFontIndex(m_fontsList.size()); | |
211 else | |
212 const_cast<Format *>(&format)->setFontIndex(m_fontsHash[format.fontKey()].fontIndex()); | |
213 } | |
214 if (!m_fontsHash.contains(format.fontKey())) { | |
215 //Still a valid font if the format has no fontData. (All font properties are default) | |
216 m_fontsList.append(format); | |
217 m_fontsHash[format.fontKey()] = format; | |
218 } | |
219 | |
220 //Fill | |
221 if (format.hasFillData() && !format.fillIndexValid()) { | |
222 //Assign proper fill index, if has fill data. | |
223 if (!m_fillsHash.contains(format.fillKey())) | |
224 const_cast<Format *>(&format)->setFillIndex(m_fillsList.size()); | |
225 else | |
226 const_cast<Format *>(&format)->setFillIndex(m_fillsHash[format.fillKey()].fillIndex()); | |
227 } | |
228 if (!m_fillsHash.contains(format.fillKey())) { | |
229 //Still a valid fill if the format has no fillData. (All fill properties are default) | |
230 m_fillsList.append(format); | |
231 m_fillsHash[format.fillKey()] = format; | |
232 } | |
233 | |
234 //Border | |
235 if (format.hasBorderData() && !format.borderIndexValid()) { | |
236 //Assign proper border index, if has border data. | |
237 if (!m_bordersHash.contains(format.borderKey())) | |
238 const_cast<Format *>(&format)->setBorderIndex(m_bordersList.size()); | |
239 else | |
240 const_cast<Format *>(&format)->setBorderIndex(m_bordersHash[format.borderKey()].borderIndex()); | |
241 } | |
242 if (!m_bordersHash.contains(format.borderKey())) { | |
243 //Still a valid border if the format has no borderData. (All border properties are default) | |
244 m_bordersList.append(format); | |
245 m_bordersHash[format.borderKey()] = format; | |
246 } | |
247 | |
248 //Format | |
249 if (!format.isEmpty() && !format.xfIndexValid()) { | |
250 if (m_xf_formatsHash.contains(format.formatKey())) | |
251 const_cast<Format *>(&format)->setXfIndex(m_xf_formatsHash[format.formatKey()].xfIndex()); | |
252 else | |
253 const_cast<Format *>(&format)->setXfIndex(m_xf_formatsList.size()); | |
254 } | |
255 if (!m_xf_formatsHash.contains(format.formatKey()) || force) { | |
256 m_xf_formatsList.append(format); | |
257 m_xf_formatsHash[format.formatKey()] = format; | |
258 } | |
259 } | |
260 | |
261 void Styles::addDxfFormat(const Format &format, bool force) | |
262 { | |
263 //numFmt | |
264 if (format.hasNumFmtData()) | |
265 fixNumFmt(format); | |
266 | |
267 if (!format.isEmpty() && !format.dxfIndexValid()) { | |
268 if (m_dxf_formatsHash.contains(format.formatKey())) | |
269 const_cast<Format *>(&format)->setDxfIndex(m_dxf_formatsHash[format.formatKey()].dxfIndex()); | |
270 else | |
271 const_cast<Format *>(&format)->setDxfIndex(m_dxf_formatsList.size()); | |
272 } | |
273 if (!m_dxf_formatsHash.contains(format.formatKey()) || force) { | |
274 m_dxf_formatsList.append(format); | |
275 m_dxf_formatsHash[format.formatKey()] = format; | |
276 } | |
277 } | |
278 | |
279 void Styles::saveToXmlFile(QIODevice *device) const | |
280 { | |
281 QXmlStreamWriter writer(device); | |
282 | |
283 writer.writeStartDocument(QStringLiteral("1.0"), true); | |
284 writer.writeStartElement(QStringLiteral("styleSheet")); | |
285 writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main")); | |
286 | |
287 writeNumFmts(writer); | |
288 writeFonts(writer); | |
289 writeFills(writer); | |
290 writeBorders(writer); | |
291 | |
292 writer.writeStartElement(QStringLiteral("cellStyleXfs")); | |
293 writer.writeAttribute(QStringLiteral("count"), QStringLiteral("1")); | |
294 writer.writeStartElement(QStringLiteral("xf")); | |
295 writer.writeAttribute(QStringLiteral("numFmtId"), QStringLiteral("0")); | |
296 writer.writeAttribute(QStringLiteral("fontId"), QStringLiteral("0")); | |
297 writer.writeAttribute(QStringLiteral("fillId"), QStringLiteral("0")); | |
298 writer.writeAttribute(QStringLiteral("borderId"), QStringLiteral("0")); | |
299 writer.writeEndElement();//xf | |
300 writer.writeEndElement();//cellStyleXfs | |
301 | |
302 writeCellXfs(writer); | |
303 | |
304 writer.writeStartElement(QStringLiteral("cellStyles")); | |
305 writer.writeAttribute(QStringLiteral("count"), QStringLiteral("1")); | |
306 writer.writeStartElement(QStringLiteral("cellStyle")); | |
307 writer.writeAttribute(QStringLiteral("name"), QStringLiteral("Normal")); | |
308 writer.writeAttribute(QStringLiteral("xfId"), QStringLiteral("0")); | |
309 writer.writeAttribute(QStringLiteral("builtinId"), QStringLiteral("0")); | |
310 writer.writeEndElement();//cellStyle | |
311 writer.writeEndElement();//cellStyles | |
312 | |
313 writeDxfs(writer); | |
314 | |
315 writer.writeStartElement(QStringLiteral("tableStyles")); | |
316 writer.writeAttribute(QStringLiteral("count"), QStringLiteral("0")); | |
317 writer.writeAttribute(QStringLiteral("defaultTableStyle"), QStringLiteral("TableStyleMedium9")); | |
318 writer.writeAttribute(QStringLiteral("defaultPivotStyle"), QStringLiteral("PivotStyleLight16")); | |
319 writer.writeEndElement();//tableStyles | |
320 | |
321 writeColors(writer); | |
322 | |
323 writer.writeEndElement();//styleSheet | |
324 writer.writeEndDocument(); | |
325 } | |
326 | |
327 void Styles::writeNumFmts(QXmlStreamWriter &writer) const | |
328 { | |
329 if (m_customNumFmtIdMap.size() == 0) | |
330 return; | |
331 | |
332 writer.writeStartElement(QStringLiteral("numFmts")); | |
333 writer.writeAttribute(QStringLiteral("count"), QString::number(m_customNumFmtIdMap.count())); | |
334 | |
335 QMapIterator<int, QSharedPointer<XlsxFormatNumberData> > it(m_customNumFmtIdMap); | |
336 while (it.hasNext()) { | |
337 it.next(); | |
338 writer.writeEmptyElement(QStringLiteral("numFmt")); | |
339 writer.writeAttribute(QStringLiteral("numFmtId"), QString::number(it.value()->formatIndex)); | |
340 writer.writeAttribute(QStringLiteral("formatCode"), it.value()->formatString); | |
341 } | |
342 writer.writeEndElement();//numFmts | |
343 } | |
344 | |
345 /* | |
346 */ | |
347 void Styles::writeFonts(QXmlStreamWriter &writer) const | |
348 { | |
349 writer.writeStartElement(QStringLiteral("fonts")); | |
350 writer.writeAttribute(QStringLiteral("count"), QString::number(m_fontsList.count())); | |
351 for (int i=0; i<m_fontsList.size(); ++i) | |
352 writeFont(writer, m_fontsList[i], false); | |
353 writer.writeEndElement();//fonts | |
354 } | |
355 | |
356 void Styles::writeFont(QXmlStreamWriter &writer, const Format &format, bool isDxf) const | |
357 { | |
358 writer.writeStartElement(QStringLiteral("font")); | |
359 | |
360 //The condense and extend elements are mainly used in dxf format | |
361 if (format.hasProperty(FormatPrivate::P_Font_Condense) | |
362 && !format.boolProperty(FormatPrivate::P_Font_Condense)) { | |
363 writer.writeEmptyElement(QStringLiteral("condense")); | |
364 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0")); | |
365 } | |
366 if (format.hasProperty(FormatPrivate::P_Font_Extend) | |
367 && !format.boolProperty(FormatPrivate::P_Font_Extend)) { | |
368 writer.writeEmptyElement(QStringLiteral("extend")); | |
369 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0")); | |
370 } | |
371 | |
372 if (format.fontBold()) | |
373 writer.writeEmptyElement(QStringLiteral("b")); | |
374 if (format.fontItalic()) | |
375 writer.writeEmptyElement(QStringLiteral("i")); | |
376 if (format.fontStrikeOut()) | |
377 writer.writeEmptyElement(QStringLiteral("strike")); | |
378 if (format.fontOutline()) | |
379 writer.writeEmptyElement(QStringLiteral("outline")); | |
380 if (format.boolProperty(FormatPrivate::P_Font_Shadow)) | |
381 writer.writeEmptyElement(QStringLiteral("shadow")); | |
382 if (format.hasProperty(FormatPrivate::P_Font_Underline)) { | |
383 Format::FontUnderline u = format.fontUnderline(); | |
384 if (u != Format::FontUnderlineNone) { | |
385 writer.writeEmptyElement(QStringLiteral("u")); | |
386 if (u== Format::FontUnderlineDouble) | |
387 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("double")); | |
388 else if (u == Format::FontUnderlineSingleAccounting) | |
389 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("singleAccounting")); | |
390 else if (u == Format::FontUnderlineDoubleAccounting) | |
391 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("doubleAccounting")); | |
392 } | |
393 } | |
394 if (format.hasProperty(FormatPrivate::P_Font_Script)) { | |
395 Format::FontScript s = format.fontScript(); | |
396 if (s != Format::FontScriptNormal) { | |
397 writer.writeEmptyElement(QStringLiteral("vertAlign")); | |
398 if (s == Format::FontScriptSuper) | |
399 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("superscript")); | |
400 else | |
401 writer.writeAttribute(QStringLiteral("val"), QStringLiteral("subscript")); | |
402 } | |
403 } | |
404 | |
405 if (!isDxf && format.hasProperty(FormatPrivate::P_Font_Size)) { | |
406 writer.writeEmptyElement(QStringLiteral("sz")); | |
407 writer.writeAttribute(QStringLiteral("val"), QString::number(format.fontSize())); | |
408 } | |
409 | |
410 if (format.hasProperty(FormatPrivate::P_Font_Color)) { | |
411 XlsxColor color = format.property(FormatPrivate::P_Font_Color).value<XlsxColor>(); | |
412 color.saveToXml(writer); | |
413 } | |
414 | |
415 if (!isDxf) { | |
416 if (!format.fontName().isEmpty()) { | |
417 writer.writeEmptyElement(QStringLiteral("name")); | |
418 writer.writeAttribute(QStringLiteral("val"), format.fontName()); | |
419 } | |
420 if (format.hasProperty(FormatPrivate::P_Font_Charset)) { | |
421 writer.writeEmptyElement(QStringLiteral("charset")); | |
422 writer.writeAttribute(QStringLiteral("val"), QString::number(format.intProperty(FormatPrivate::P_Font_Charset))); | |
423 } | |
424 if (format.hasProperty(FormatPrivate::P_Font_Family)) { | |
425 writer.writeEmptyElement(QStringLiteral("family")); | |
426 writer.writeAttribute(QStringLiteral("val"), QString::number(format.intProperty(FormatPrivate::P_Font_Family))); | |
427 } | |
428 | |
429 if (format.hasProperty(FormatPrivate::P_Font_Scheme)) { | |
430 writer.writeEmptyElement(QStringLiteral("scheme")); | |
431 writer.writeAttribute(QStringLiteral("val"), format.stringProperty(FormatPrivate::P_Font_Scheme)); | |
432 } | |
433 } | |
434 writer.writeEndElement(); //font | |
435 } | |
436 | |
437 void Styles::writeFills(QXmlStreamWriter &writer) const | |
438 { | |
439 writer.writeStartElement(QStringLiteral("fills")); | |
440 writer.writeAttribute(QStringLiteral("count"), QString::number(m_fillsList.size())); | |
441 | |
442 for (int i=0; i<m_fillsList.size(); ++i) | |
443 writeFill(writer, m_fillsList[i]); | |
444 | |
445 writer.writeEndElement(); //fills | |
446 } | |
447 | |
448 void Styles::writeFill(QXmlStreamWriter &writer, const Format &fill, bool isDxf) const | |
449 { | |
450 static QMap<int, QString> patternStrings; | |
451 if (patternStrings.isEmpty()) { | |
452 patternStrings[Format::PatternNone] = QStringLiteral("none"); | |
453 patternStrings[Format::PatternSolid] = QStringLiteral("solid"); | |
454 patternStrings[Format::PatternMediumGray] = QStringLiteral("mediumGray"); | |
455 patternStrings[Format::PatternDarkGray] = QStringLiteral("darkGray"); | |
456 patternStrings[Format::PatternLightGray] = QStringLiteral("lightGray"); | |
457 patternStrings[Format::PatternDarkHorizontal] = QStringLiteral("darkHorizontal"); | |
458 patternStrings[Format::PatternDarkVertical] = QStringLiteral("darkVertical"); | |
459 patternStrings[Format::PatternDarkDown] = QStringLiteral("darkDown"); | |
460 patternStrings[Format::PatternDarkUp] = QStringLiteral("darkUp"); | |
461 patternStrings[Format::PatternDarkGrid] = QStringLiteral("darkGrid"); | |
462 patternStrings[Format::PatternDarkTrellis] = QStringLiteral("darkTrellis"); | |
463 patternStrings[Format::PatternLightHorizontal] = QStringLiteral("lightHorizontal"); | |
464 patternStrings[Format::PatternLightVertical] = QStringLiteral("lightVertical"); | |
465 patternStrings[Format::PatternLightDown] = QStringLiteral("lightDown"); | |
466 patternStrings[Format::PatternLightUp] = QStringLiteral("lightUp"); | |
467 patternStrings[Format::PatternLightTrellis] = QStringLiteral("lightTrellis"); | |
468 patternStrings[Format::PatternGray125] = QStringLiteral("gray125"); | |
469 patternStrings[Format::PatternGray0625] = QStringLiteral("gray0625"); | |
470 patternStrings[Format::PatternLightGrid] = QStringLiteral("lightGrid"); | |
471 } | |
472 | |
473 writer.writeStartElement(QStringLiteral("fill")); | |
474 writer.writeStartElement(QStringLiteral("patternFill")); | |
475 Format::FillPattern pattern = fill.fillPattern(); | |
476 // For normal fill formats, Excel prefer to outputing the default "none" attribute | |
477 // But for dxf, Excel prefer to omiting the default "none" | |
478 // Though not make any difference, but it make easier to compare origin files with generate files during debug | |
479 if (!(pattern == Format::PatternNone && isDxf)) | |
480 writer.writeAttribute(QStringLiteral("patternType"), patternStrings[pattern]); | |
481 // For a solid fill, Excel reverses the role of foreground and background colours | |
482 if (fill.fillPattern() == Format::PatternSolid) { | |
483 if (fill.hasProperty(FormatPrivate::P_Fill_BgColor)) | |
484 fill.property(FormatPrivate::P_Fill_BgColor).value<XlsxColor>().saveToXml(writer, QStringLiteral("fgColor")); | |
485 if (fill.hasProperty(FormatPrivate::P_Fill_FgColor)) | |
486 fill.property(FormatPrivate::P_Fill_FgColor).value<XlsxColor>().saveToXml(writer, QStringLiteral("bgColor")); | |
487 } else { | |
488 if (fill.hasProperty(FormatPrivate::P_Fill_FgColor)) | |
489 fill.property(FormatPrivate::P_Fill_FgColor).value<XlsxColor>().saveToXml(writer, QStringLiteral("fgColor")); | |
490 if (fill.hasProperty(FormatPrivate::P_Fill_BgColor)) | |
491 fill.property(FormatPrivate::P_Fill_BgColor).value<XlsxColor>().saveToXml(writer, QStringLiteral("bgColor")); | |
492 } | |
493 writer.writeEndElement();//patternFill | |
494 writer.writeEndElement();//fill | |
495 } | |
496 | |
497 void Styles::writeBorders(QXmlStreamWriter &writer) const | |
498 { | |
499 writer.writeStartElement(QStringLiteral("borders")); | |
500 writer.writeAttribute(QStringLiteral("count"), QString::number(m_bordersList.count())); | |
501 for (int i=0; i<m_bordersList.size(); ++i) | |
502 writeBorder(writer, m_bordersList[i]); | |
503 writer.writeEndElement();//borders | |
504 } | |
505 | |
506 void Styles::writeBorder(QXmlStreamWriter &writer, const Format &border, bool isDxf) const | |
507 { | |
508 writer.writeStartElement(QStringLiteral("border")); | |
509 if (border.hasProperty(FormatPrivate::P_Border_DiagonalType)) { | |
510 Format::DiagonalBorderType t = border.diagonalBorderType(); | |
511 if (t == Format::DiagonalBorderUp) { | |
512 writer.writeAttribute(QStringLiteral("diagonalUp"), QStringLiteral("1")); | |
513 } else if (t == Format::DiagonalBorderDown) { | |
514 writer.writeAttribute(QStringLiteral("diagonalDown"), QStringLiteral("1")); | |
515 } else if (t == Format::DiagnoalBorderBoth) { | |
516 writer.writeAttribute(QStringLiteral("diagonalUp"), QStringLiteral("1")); | |
517 writer.writeAttribute(QStringLiteral("diagonalDown"), QStringLiteral("1")); | |
518 } | |
519 } | |
520 | |
521 writeSubBorder(writer, QStringLiteral("left"), border.leftBorderStyle(), border.property(FormatPrivate::P_Border_LeftColor).value<XlsxColor>()); | |
522 writeSubBorder(writer, QStringLiteral("right"), border.rightBorderStyle(), border.property(FormatPrivate::P_Border_RightColor).value<XlsxColor>()); | |
523 writeSubBorder(writer, QStringLiteral("top"), border.topBorderStyle(), border.property(FormatPrivate::P_Border_TopColor).value<XlsxColor>()); | |
524 writeSubBorder(writer, QStringLiteral("bottom"), border.bottomBorderStyle(), border.property(FormatPrivate::P_Border_BottomColor).value<XlsxColor>()); | |
525 | |
526 //Condition DXF formats don't allow diagonal style | |
527 if (!isDxf) | |
528 writeSubBorder(writer, QStringLiteral("diagonal"), border.diagonalBorderStyle(), border.property(FormatPrivate::P_Border_DiagonalColor).value<XlsxColor>()); | |
529 | |
530 if (isDxf) { | |
531 // writeSubBorder(wirter, QStringLiteral("vertical"), ); | |
532 // writeSubBorder(writer, QStringLiteral("horizontal"), ); | |
533 } | |
534 | |
535 writer.writeEndElement();//border | |
536 } | |
537 | |
538 void Styles::writeSubBorder(QXmlStreamWriter &writer, const QString &type, int style, const XlsxColor &color) const | |
539 { | |
540 if (style == Format::BorderNone) { | |
541 writer.writeEmptyElement(type); | |
542 return; | |
543 } | |
544 | |
545 static QMap<int, QString> stylesString; | |
546 if (stylesString.isEmpty()) { | |
547 stylesString[Format::BorderNone] = QStringLiteral("none"); | |
548 stylesString[Format::BorderThin] = QStringLiteral("thin"); | |
549 stylesString[Format::BorderMedium] = QStringLiteral("medium"); | |
550 stylesString[Format::BorderDashed] = QStringLiteral("dashed"); | |
551 stylesString[Format::BorderDotted] = QStringLiteral("dotted"); | |
552 stylesString[Format::BorderThick] = QStringLiteral("thick"); | |
553 stylesString[Format::BorderDouble] = QStringLiteral("double"); | |
554 stylesString[Format::BorderHair] = QStringLiteral("hair"); | |
555 stylesString[Format::BorderMediumDashed] = QStringLiteral("mediumDashed"); | |
556 stylesString[Format::BorderDashDot] = QStringLiteral("dashDot"); | |
557 stylesString[Format::BorderMediumDashDot] = QStringLiteral("mediumDashDot"); | |
558 stylesString[Format::BorderDashDotDot] = QStringLiteral("dashDotDot"); | |
559 stylesString[Format::BorderMediumDashDotDot] = QStringLiteral("mediumDashDotDot"); | |
560 stylesString[Format::BorderSlantDashDot] = QStringLiteral("slantDashDot"); | |
561 } | |
562 | |
563 writer.writeStartElement(type); | |
564 writer.writeAttribute(QStringLiteral("style"), stylesString[style]); | |
565 color.saveToXml(writer); //write color element | |
566 | |
567 writer.writeEndElement();//type | |
568 } | |
569 | |
570 void Styles::writeCellXfs(QXmlStreamWriter &writer) const | |
571 { | |
572 writer.writeStartElement(QStringLiteral("cellXfs")); | |
573 writer.writeAttribute(QStringLiteral("count"), QString::number(m_xf_formatsList.size())); | |
574 foreach (const Format &format, m_xf_formatsList) { | |
575 int xf_id = 0; | |
576 writer.writeStartElement(QStringLiteral("xf")); | |
577 writer.writeAttribute(QStringLiteral("numFmtId"), QString::number(format.numberFormatIndex())); | |
578 writer.writeAttribute(QStringLiteral("fontId"), QString::number(format.fontIndex())); | |
579 writer.writeAttribute(QStringLiteral("fillId"), QString::number(format.fillIndex())); | |
580 writer.writeAttribute(QStringLiteral("borderId"), QString::number(format.borderIndex())); | |
581 writer.writeAttribute(QStringLiteral("xfId"), QString::number(xf_id)); | |
582 if (format.hasNumFmtData()) | |
583 writer.writeAttribute(QStringLiteral("applyNumberFormat"), QStringLiteral("1")); | |
584 if (format.hasFontData()) | |
585 writer.writeAttribute(QStringLiteral("applyFont"), QStringLiteral("1")); | |
586 if (format.hasFillData()) | |
587 writer.writeAttribute(QStringLiteral("applyFill"), QStringLiteral("1")); | |
588 if (format.hasBorderData()) | |
589 writer.writeAttribute(QStringLiteral("applyBorder"), QStringLiteral("1")); | |
590 if (format.hasAlignmentData()) | |
591 writer.writeAttribute(QStringLiteral("applyAlignment"), QStringLiteral("1")); | |
592 | |
593 if (format.hasAlignmentData()) { | |
594 writer.writeEmptyElement(QStringLiteral("alignment")); | |
595 if (format.hasProperty(FormatPrivate::P_Alignment_AlignH)) { | |
596 switch (format.horizontalAlignment()) { | |
597 case Format::AlignLeft: | |
598 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("left")); | |
599 break; | |
600 case Format::AlignHCenter: | |
601 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("center")); | |
602 break; | |
603 case Format::AlignRight: | |
604 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("right")); | |
605 break; | |
606 case Format::AlignHFill: | |
607 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("fill")); | |
608 break; | |
609 case Format::AlignHJustify: | |
610 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("justify")); | |
611 break; | |
612 case Format::AlignHMerge: | |
613 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("centerContinuous")); | |
614 break; | |
615 case Format::AlignHDistributed: | |
616 writer.writeAttribute(QStringLiteral("horizontal"), QStringLiteral("distributed")); | |
617 break; | |
618 default: | |
619 break; | |
620 } | |
621 } | |
622 | |
623 if (format.hasProperty(FormatPrivate::P_Alignment_AlignV)) { | |
624 switch (format.verticalAlignment()) { | |
625 case Format::AlignTop: | |
626 writer.writeAttribute(QStringLiteral("vertical"), QStringLiteral("top")); | |
627 break; | |
628 case Format::AlignVCenter: | |
629 writer.writeAttribute(QStringLiteral("vertical"), QStringLiteral("center")); | |
630 break; | |
631 case Format::AlignVJustify: | |
632 writer.writeAttribute(QStringLiteral("vertical"), QStringLiteral("justify")); | |
633 break; | |
634 case Format::AlignVDistributed: | |
635 writer.writeAttribute(QStringLiteral("vertical"), QStringLiteral("distributed")); | |
636 break; | |
637 default: | |
638 break; | |
639 } | |
640 } | |
641 if (format.hasProperty(FormatPrivate::P_Alignment_Indent)) | |
642 writer.writeAttribute(QStringLiteral("indent"), QString::number(format.indent())); | |
643 if (format.hasProperty(FormatPrivate::P_Alignment_Wrap) && format.textWrap()) | |
644 writer.writeAttribute(QStringLiteral("wrapText"), QStringLiteral("1")); | |
645 if (format.hasProperty(FormatPrivate::P_Alignment_ShinkToFit) && format.shrinkToFit()) | |
646 writer.writeAttribute(QStringLiteral("shrinkToFit"), QStringLiteral("1")); | |
647 if (format.hasProperty(FormatPrivate::P_Alignment_Rotation)) | |
648 writer.writeAttribute(QStringLiteral("textRotation"), QString::number(format.rotation())); | |
649 } | |
650 | |
651 writer.writeEndElement();//xf | |
652 } | |
653 writer.writeEndElement();//cellXfs | |
654 } | |
655 | |
656 void Styles::writeDxfs(QXmlStreamWriter &writer) const | |
657 { | |
658 writer.writeStartElement(QStringLiteral("dxfs")); | |
659 writer.writeAttribute(QStringLiteral("count"), QString::number(m_dxf_formatsList.size())); | |
660 foreach (const Format &format, m_dxf_formatsList) | |
661 writeDxf(writer, format); | |
662 writer.writeEndElement(); //dxfs | |
663 } | |
664 | |
665 void Styles::writeDxf(QXmlStreamWriter &writer, const Format &format) const | |
666 { | |
667 writer.writeStartElement(QStringLiteral("dxf")); | |
668 | |
669 if (format.hasFontData()) | |
670 writeFont(writer, format, true); | |
671 | |
672 if (format.hasNumFmtData()) { | |
673 writer.writeEmptyElement(QStringLiteral("numFmt")); | |
674 writer.writeAttribute(QStringLiteral("numFmtId"), QString::number(format.numberFormatIndex())); | |
675 writer.writeAttribute(QStringLiteral("formatCode"), format.numberFormat()); | |
676 } | |
677 | |
678 if (format.hasFillData()) | |
679 writeFill(writer, format, true); | |
680 | |
681 if (format.hasBorderData()) | |
682 writeBorder(writer, format, true); | |
683 | |
684 writer.writeEndElement();//dxf | |
685 } | |
686 | |
687 void Styles::writeColors(QXmlStreamWriter &writer) const | |
688 { | |
689 if (m_isIndexedColorsDefault) //Don't output the default indexdeColors | |
690 return; | |
691 | |
692 writer.writeStartElement(QStringLiteral("colors")); | |
693 | |
694 writer.writeStartElement(QStringLiteral("indexedColors")); | |
695 foreach(QColor color, m_indexedColors) { | |
696 writer.writeEmptyElement(QStringLiteral("rgbColor")); | |
697 writer.writeAttribute(QStringLiteral("rgb"), XlsxColor::toARGBString(color)); | |
698 } | |
699 | |
700 writer.writeEndElement();//indexedColors | |
701 | |
702 writer.writeEndElement();//colors | |
703 } | |
704 | |
705 bool Styles::readNumFmts(QXmlStreamReader &reader) | |
706 { | |
707 Q_ASSERT(reader.name() == QLatin1String("numFmts")); | |
708 QXmlStreamAttributes attributes = reader.attributes(); | |
709 bool hasCount = attributes.hasAttribute(QLatin1String("count")); | |
710 int count = hasCount ? attributes.value(QLatin1String("count")).toString().toInt() : -1; | |
711 | |
712 //Read utill we find the numFmts end tag or .... | |
713 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
714 && reader.name() == QLatin1String("numFmts"))) { | |
715 reader.readNextStartElement(); | |
716 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
717 if (reader.name() == QLatin1String("numFmt")) { | |
718 QXmlStreamAttributes attributes = reader.attributes(); | |
719 QSharedPointer<XlsxFormatNumberData> fmt (new XlsxFormatNumberData); | |
720 fmt->formatIndex = attributes.value(QLatin1String("numFmtId")).toString().toInt(); | |
721 fmt->formatString = attributes.value(QLatin1String("formatCode")).toString(); | |
722 if (fmt->formatIndex >= m_nextCustomNumFmtId) | |
723 m_nextCustomNumFmtId = fmt->formatIndex + 1; | |
724 m_customNumFmtIdMap.insert(fmt->formatIndex, fmt); | |
725 m_customNumFmtsHash.insert(fmt->formatString, fmt); | |
726 } | |
727 } | |
728 } | |
729 | |
730 if (reader.hasError()) | |
731 qWarning()<<reader.errorString(); | |
732 | |
733 if (hasCount && (count != m_customNumFmtIdMap.size())) | |
734 qWarning("error read custom numFmts"); | |
735 | |
736 return true; | |
737 } | |
738 | |
739 bool Styles::readFonts(QXmlStreamReader &reader) | |
740 { | |
741 Q_ASSERT(reader.name() == QLatin1String("fonts")); | |
742 QXmlStreamAttributes attributes = reader.attributes(); | |
743 bool hasCount = attributes.hasAttribute(QLatin1String("count")); | |
744 int count = hasCount ? attributes.value(QLatin1String("count")).toString().toInt() : -1; | |
745 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
746 && reader.name() == QLatin1String("fonts"))) { | |
747 reader.readNextStartElement(); | |
748 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
749 if (reader.name() == QLatin1String("font")) { | |
750 Format format; | |
751 readFont(reader, format); | |
752 m_fontsList.append(format); | |
753 m_fontsHash.insert(format.fontKey(), format); | |
754 if (format.isValid()) | |
755 format.setFontIndex(m_fontsList.size()-1); | |
756 } | |
757 } | |
758 } | |
759 if (reader.hasError()) | |
760 qWarning()<<reader.errorString(); | |
761 | |
762 if (hasCount && (count != m_fontsList.size())) | |
763 qWarning("error read fonts"); | |
764 return true; | |
765 } | |
766 | |
767 bool Styles::readFont(QXmlStreamReader &reader, Format &format) | |
768 { | |
769 Q_ASSERT(reader.name() == QLatin1String("font")); | |
770 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
771 && reader.name() == QLatin1String("font"))) { | |
772 reader.readNextStartElement(); | |
773 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
774 QXmlStreamAttributes attributes = reader.attributes(); | |
775 if (reader.name() == QLatin1String("name")) { | |
776 format.setFontName(attributes.value(QLatin1String("val")).toString()); | |
777 } else if (reader.name() == QLatin1String("charset")) { | |
778 format.setProperty(FormatPrivate::P_Font_Charset, attributes.value(QLatin1String("val")).toString().toInt()); | |
779 } else if (reader.name() == QLatin1String("family")) { | |
780 format.setProperty(FormatPrivate::P_Font_Family, attributes.value(QLatin1String("val")).toString().toInt()); | |
781 } else if (reader.name() == QLatin1String("b")) { | |
782 format.setFontBold(true); | |
783 } else if (reader.name() == QLatin1String("i")) { | |
784 format.setFontItalic(true); | |
785 } else if (reader.name() == QLatin1String("strike")) { | |
786 format.setFontStrikeOut(true); | |
787 } else if (reader.name() == QLatin1String("outline")) { | |
788 format.setFontOutline(true); | |
789 } else if (reader.name() == QLatin1String("shadow")) { | |
790 format.setProperty(FormatPrivate::P_Font_Shadow, true); | |
791 } else if (reader.name() == QLatin1String("condense")) { | |
792 format.setProperty(FormatPrivate::P_Font_Condense, attributes.value(QLatin1String("val")).toString().toInt()); | |
793 } else if (reader.name() == QLatin1String("extend")) { | |
794 format.setProperty(FormatPrivate::P_Font_Extend, attributes.value(QLatin1String("val")).toString().toInt()); | |
795 } else if (reader.name() == QLatin1String("color")) { | |
796 XlsxColor color; | |
797 color.loadFromXml(reader); | |
798 format.setProperty(FormatPrivate::P_Font_Color, color); | |
799 } else if (reader.name() == QLatin1String("sz")) { | |
800 int sz = attributes.value(QLatin1String("val")).toString().toInt(); | |
801 format.setFontSize(sz); | |
802 } else if (reader.name() == QLatin1String("u")) { | |
803 QString value = attributes.value(QLatin1String("val")).toString(); | |
804 if (value == QLatin1String("double")) | |
805 format.setFontUnderline(Format::FontUnderlineDouble); | |
806 else if (value == QLatin1String("doubleAccounting")) | |
807 format.setFontUnderline(Format::FontUnderlineDoubleAccounting); | |
808 else if (value == QLatin1String("singleAccounting")) | |
809 format.setFontUnderline(Format::FontUnderlineSingleAccounting); | |
810 else | |
811 format.setFontUnderline(Format::FontUnderlineSingle); | |
812 } else if (reader.name() == QLatin1String("vertAlign")) { | |
813 QString value = attributes.value(QLatin1String("val")).toString(); | |
814 if (value == QLatin1String("superscript")) | |
815 format.setFontScript(Format::FontScriptSuper); | |
816 else if (value == QLatin1String("subscript")) | |
817 format.setFontScript(Format::FontScriptSub); | |
818 } else if (reader.name() == QLatin1String("scheme")) { | |
819 format.setProperty(FormatPrivate::P_Font_Scheme, attributes.value(QLatin1String("val")).toString()); | |
820 } | |
821 } | |
822 } | |
823 return true; | |
824 } | |
825 | |
826 bool Styles::readFills(QXmlStreamReader &reader) | |
827 { | |
828 Q_ASSERT(reader.name() == QLatin1String("fills")); | |
829 | |
830 QXmlStreamAttributes attributes = reader.attributes(); | |
831 bool hasCount = attributes.hasAttribute(QLatin1String("count")); | |
832 int count = hasCount ? attributes.value(QLatin1String("count")).toString().toInt() : -1; | |
833 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
834 && reader.name() == QLatin1String("fills"))) { | |
835 reader.readNextStartElement(); | |
836 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
837 if (reader.name() == QLatin1String("fill")) { | |
838 Format fill; | |
839 readFill(reader, fill); | |
840 m_fillsList.append(fill); | |
841 m_fillsHash.insert(fill.fillKey(), fill); | |
842 if (fill.isValid()) | |
843 fill.setFillIndex(m_fillsList.size()-1); | |
844 } | |
845 } | |
846 } | |
847 if (reader.hasError()) | |
848 qWarning()<<reader.errorString(); | |
849 | |
850 if (hasCount && (count != m_fillsList.size())) | |
851 qWarning("error read fills"); | |
852 return true; | |
853 } | |
854 | |
855 bool Styles::readFill(QXmlStreamReader &reader, Format &fill) | |
856 { | |
857 Q_ASSERT(reader.name() == QLatin1String("fill")); | |
858 | |
859 static QMap<QString, Format::FillPattern> patternValues; | |
860 if (patternValues.isEmpty()) { | |
861 patternValues[QStringLiteral("none")] = Format::PatternNone; | |
862 patternValues[QStringLiteral("solid")] = Format::PatternSolid; | |
863 patternValues[QStringLiteral("mediumGray")] = Format::PatternMediumGray; | |
864 patternValues[QStringLiteral("darkGray")] = Format::PatternDarkGray; | |
865 patternValues[QStringLiteral("lightGray")] = Format::PatternLightGray; | |
866 patternValues[QStringLiteral("darkHorizontal")] = Format::PatternDarkHorizontal; | |
867 patternValues[QStringLiteral("darkVertical")] = Format::PatternDarkVertical; | |
868 patternValues[QStringLiteral("darkDown")] = Format::PatternDarkDown; | |
869 patternValues[QStringLiteral("darkUp")] = Format::PatternDarkUp; | |
870 patternValues[QStringLiteral("darkGrid")] = Format::PatternDarkGrid; | |
871 patternValues[QStringLiteral("darkTrellis")] = Format::PatternDarkTrellis; | |
872 patternValues[QStringLiteral("lightHorizontal")] = Format::PatternLightHorizontal; | |
873 patternValues[QStringLiteral("lightVertical")] = Format::PatternLightVertical; | |
874 patternValues[QStringLiteral("lightDown")] = Format::PatternLightDown; | |
875 patternValues[QStringLiteral("lightUp")] = Format::PatternLightUp; | |
876 patternValues[QStringLiteral("lightTrellis")] = Format::PatternLightTrellis; | |
877 patternValues[QStringLiteral("gray125")] = Format::PatternGray125; | |
878 patternValues[QStringLiteral("gray0625")] = Format::PatternGray0625; | |
879 patternValues[QStringLiteral("lightGrid")] = Format::PatternLightGrid; | |
880 } | |
881 | |
882 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("fill"))) { | |
883 reader.readNextStartElement(); | |
884 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
885 if (reader.name() == QLatin1String("patternFill")) { | |
886 QXmlStreamAttributes attributes = reader.attributes(); | |
887 if (attributes.hasAttribute(QLatin1String("patternType"))) { | |
888 QString pattern = attributes.value(QLatin1String("patternType")).toString(); | |
889 fill.setFillPattern(patternValues.contains(pattern) ? patternValues[pattern] : Format::PatternNone); | |
890 | |
891 //parse foreground and background colors if they exist | |
892 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("patternFill"))) { | |
893 reader.readNextStartElement(); | |
894 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
895 if (reader.name() == QLatin1String("fgColor")) { | |
896 XlsxColor c; | |
897 c.loadFromXml(reader); | |
898 if (fill.fillPattern() == Format::PatternSolid) | |
899 fill.setProperty(FormatPrivate::P_Fill_BgColor, c); | |
900 else | |
901 fill.setProperty(FormatPrivate::P_Fill_FgColor, c); | |
902 } else if (reader.name() == QLatin1String("bgColor")) { | |
903 XlsxColor c; | |
904 c.loadFromXml(reader); | |
905 if (fill.fillPattern() == Format::PatternSolid) | |
906 fill.setProperty(FormatPrivate::P_Fill_FgColor, c); | |
907 else | |
908 fill.setProperty(FormatPrivate::P_Fill_BgColor, c); | |
909 } | |
910 } | |
911 } | |
912 } | |
913 } | |
914 } | |
915 } | |
916 | |
917 return true; | |
918 } | |
919 | |
920 bool Styles::readBorders(QXmlStreamReader &reader) | |
921 { | |
922 Q_ASSERT(reader.name() == QLatin1String("borders")); | |
923 | |
924 QXmlStreamAttributes attributes = reader.attributes(); | |
925 bool hasCount = attributes.hasAttribute(QLatin1String("count")); | |
926 int count = hasCount ? attributes.value(QLatin1String("count")).toString().toInt() : -1; | |
927 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
928 && reader.name() == QLatin1String("borders"))) { | |
929 reader.readNextStartElement(); | |
930 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
931 if (reader.name() == QLatin1String("border")) { | |
932 Format border; | |
933 readBorder(reader, border); | |
934 m_bordersList.append(border); | |
935 m_bordersHash.insert(border.borderKey(), border); | |
936 if (border.isValid()) | |
937 border.setBorderIndex(m_bordersList.size()-1); | |
938 } | |
939 } | |
940 } | |
941 | |
942 if (reader.hasError()) | |
943 qWarning()<<reader.errorString(); | |
944 | |
945 if (hasCount && (count != m_bordersList.size())) | |
946 qWarning("error read borders"); | |
947 | |
948 return true; | |
949 } | |
950 | |
951 bool Styles::readBorder(QXmlStreamReader &reader, Format &border) | |
952 { | |
953 Q_ASSERT(reader.name() == QLatin1String("border")); | |
954 | |
955 QXmlStreamAttributes attributes = reader.attributes(); | |
956 bool isUp = attributes.hasAttribute(QLatin1String("diagonalUp")); | |
957 bool isDown = attributes.hasAttribute(QLatin1String("diagonalUp")); | |
958 if (isUp && isDown) | |
959 border.setDiagonalBorderType(Format::DiagnoalBorderBoth); | |
960 else if (isUp) | |
961 border.setDiagonalBorderType(Format::DiagonalBorderUp); | |
962 else if (isDown) | |
963 border.setDiagonalBorderType(Format::DiagonalBorderDown); | |
964 | |
965 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("border"))) { | |
966 reader.readNextStartElement(); | |
967 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
968 if (reader.name() == QLatin1String("left") || reader.name() == QLatin1String("right") | |
969 || reader.name() == QLatin1String("top") || reader.name() == QLatin1String("bottom") | |
970 || reader.name() == QLatin1String("diagonal") ) { | |
971 Format::BorderStyle style(Format::BorderNone); | |
972 XlsxColor color; | |
973 readSubBorder(reader, reader.name().toString(), style, color); | |
974 | |
975 if (reader.name() == QLatin1String("left")) { | |
976 border.setLeftBorderStyle(style); | |
977 if (!color.isInvalid()) | |
978 border.setProperty(FormatPrivate::P_Border_LeftColor, color); | |
979 } else if (reader.name() == QLatin1String("right")) { | |
980 border.setRightBorderStyle(style); | |
981 if (!color.isInvalid()) | |
982 border.setProperty(FormatPrivate::P_Border_RightColor, color); | |
983 } else if (reader.name() == QLatin1String("top")) { | |
984 border.setTopBorderStyle(style); | |
985 if (!color.isInvalid()) | |
986 border.setProperty(FormatPrivate::P_Border_TopColor, color); | |
987 } else if (reader.name() == QLatin1String("bottom")) { | |
988 border.setBottomBorderStyle(style); | |
989 if (!color.isInvalid()) | |
990 border.setProperty(FormatPrivate::P_Border_BottomColor, color); | |
991 } else if (reader.name() == QLatin1String("diagonal")) { | |
992 border.setDiagonalBorderStyle(style); | |
993 if (!color.isInvalid()) | |
994 border.setProperty(FormatPrivate::P_Border_DiagonalColor, color); | |
995 } | |
996 } | |
997 } | |
998 | |
999 if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("border")) | |
1000 break; | |
1001 } | |
1002 | |
1003 return true; | |
1004 } | |
1005 | |
1006 bool Styles::readSubBorder(QXmlStreamReader &reader, const QString &name, Format::BorderStyle &style, XlsxColor &color) | |
1007 { | |
1008 Q_ASSERT(reader.name() == name); | |
1009 | |
1010 static QMap<QString, Format::BorderStyle> stylesStringsMap; | |
1011 if (stylesStringsMap.isEmpty()) { | |
1012 stylesStringsMap[QStringLiteral("none")] = Format::BorderNone; | |
1013 stylesStringsMap[QStringLiteral("thin")] = Format::BorderThin; | |
1014 stylesStringsMap[QStringLiteral("medium")] = Format::BorderMedium; | |
1015 stylesStringsMap[QStringLiteral("dashed")] = Format::BorderDashed; | |
1016 stylesStringsMap[QStringLiteral("dotted")] = Format::BorderDotted; | |
1017 stylesStringsMap[QStringLiteral("thick")] = Format::BorderThick; | |
1018 stylesStringsMap[QStringLiteral("double")] = Format::BorderDouble; | |
1019 stylesStringsMap[QStringLiteral("hair")] = Format::BorderHair; | |
1020 stylesStringsMap[QStringLiteral("mediumDashed")] = Format::BorderMediumDashed; | |
1021 stylesStringsMap[QStringLiteral("dashDot")] = Format::BorderDashDot; | |
1022 stylesStringsMap[QStringLiteral("mediumDashDot")] = Format::BorderMediumDashDot; | |
1023 stylesStringsMap[QStringLiteral("dashDotDot")] = Format::BorderDashDotDot; | |
1024 stylesStringsMap[QStringLiteral("mediumDashDotDot")] = Format::BorderMediumDashDotDot; | |
1025 stylesStringsMap[QStringLiteral("slantDashDot")] = Format::BorderSlantDashDot; | |
1026 } | |
1027 | |
1028 QXmlStreamAttributes attributes = reader.attributes(); | |
1029 if (attributes.hasAttribute(QLatin1String("style"))) { | |
1030 QString styleString = attributes.value(QLatin1String("style")).toString(); | |
1031 if (stylesStringsMap.contains(styleString)) { | |
1032 //get style | |
1033 style = stylesStringsMap[styleString]; | |
1034 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == name)) { | |
1035 reader.readNextStartElement(); | |
1036 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
1037 if (reader.name() == QLatin1String("color")) | |
1038 color.loadFromXml(reader); | |
1039 } | |
1040 } | |
1041 } | |
1042 } | |
1043 | |
1044 return true; | |
1045 } | |
1046 | |
1047 bool Styles::readCellXfs(QXmlStreamReader &reader) | |
1048 { | |
1049 Q_ASSERT(reader.name() == QLatin1String("cellXfs")); | |
1050 QXmlStreamAttributes attributes = reader.attributes(); | |
1051 bool hasCount = attributes.hasAttribute(QLatin1String("count")); | |
1052 int count = hasCount ? attributes.value(QLatin1String("count")).toString().toInt() : -1; | |
1053 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
1054 && reader.name() == QLatin1String("cellXfs"))) { | |
1055 reader.readNextStartElement(); | |
1056 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
1057 if (reader.name() == QLatin1String("xf")) { | |
1058 | |
1059 Format format; | |
1060 QXmlStreamAttributes xfAttrs = reader.attributes(); | |
1061 | |
1062 // qDebug()<<reader.name()<<reader.tokenString()<<" ........."; | |
1063 // for (int i=0; i<xfAttrs.size(); ++i) | |
1064 // qDebug()<<"... "<<i<<" "<<xfAttrs[i].name()<<xfAttrs[i].value(); | |
1065 | |
1066 if (xfAttrs.hasAttribute(QLatin1String("numFmtId"))) { | |
1067 int numFmtIndex = xfAttrs.value(QLatin1String("numFmtId")).toString().toInt(); | |
1068 bool apply = parseXsdBoolean(xfAttrs.value(QLatin1String("applyNumberFormat")).toString()); | |
1069 if(apply) { | |
1070 if (!m_customNumFmtIdMap.contains(numFmtIndex)) | |
1071 format.setNumberFormatIndex(numFmtIndex); | |
1072 else | |
1073 format.setNumberFormat(numFmtIndex, m_customNumFmtIdMap[numFmtIndex]->formatString); | |
1074 } | |
1075 } | |
1076 | |
1077 if (xfAttrs.hasAttribute(QLatin1String("fontId"))) { | |
1078 int fontIndex = xfAttrs.value(QLatin1String("fontId")).toString().toInt(); | |
1079 if (fontIndex >= m_fontsList.size()) { | |
1080 qDebug("Error read styles.xml, cellXfs fontId"); | |
1081 } else { | |
1082 bool apply = parseXsdBoolean(xfAttrs.value(QLatin1String("applyFont")).toString()); | |
1083 if(apply) { | |
1084 Format fontFormat = m_fontsList[fontIndex]; | |
1085 for (int i=FormatPrivate::P_Font_STARTID; i<FormatPrivate::P_Font_ENDID; ++i) { | |
1086 if (fontFormat.hasProperty(i)) | |
1087 format.setProperty(i, fontFormat.property(i)); | |
1088 } | |
1089 } | |
1090 } | |
1091 } | |
1092 | |
1093 if (xfAttrs.hasAttribute(QLatin1String("fillId"))) { | |
1094 int id = xfAttrs.value(QLatin1String("fillId")).toString().toInt(); | |
1095 if (id >= m_fillsList.size()) { | |
1096 qDebug("Error read styles.xml, cellXfs fillId"); | |
1097 } else { | |
1098 bool apply = parseXsdBoolean(xfAttrs.value(QLatin1String("applyFill")).toString()); | |
1099 if(apply) { | |
1100 Format fillFormat = m_fillsList[id]; | |
1101 for (int i=FormatPrivate::P_Fill_STARTID; i<FormatPrivate::P_Fill_ENDID; ++i) { | |
1102 if (fillFormat.hasProperty(i)) | |
1103 format.setProperty(i, fillFormat.property(i)); | |
1104 } | |
1105 } | |
1106 } | |
1107 } | |
1108 | |
1109 if (xfAttrs.hasAttribute(QLatin1String("borderId"))) { | |
1110 int id = xfAttrs.value(QLatin1String("borderId")).toString().toInt(); | |
1111 if (id >= m_bordersList.size()) { | |
1112 qDebug("Error read styles.xml, cellXfs borderId"); | |
1113 } else { | |
1114 bool apply = parseXsdBoolean(xfAttrs.value(QLatin1String("applyBorder")).toString()); | |
1115 if(apply) { | |
1116 Format borderFormat = m_bordersList[id]; | |
1117 for (int i=FormatPrivate::P_Border_STARTID; i<FormatPrivate::P_Border_ENDID; ++i) { | |
1118 if (borderFormat.hasProperty(i)) | |
1119 format.setProperty(i, borderFormat.property(i)); | |
1120 } | |
1121 } | |
1122 } | |
1123 } | |
1124 | |
1125 bool apply = parseXsdBoolean(xfAttrs.value(QLatin1String("applyAlignment")).toString()); | |
1126 if(apply) { | |
1127 reader.readNextStartElement(); | |
1128 if (reader.name() == QLatin1String("alignment")) { | |
1129 QXmlStreamAttributes alignAttrs = reader.attributes(); | |
1130 | |
1131 if (alignAttrs.hasAttribute(QLatin1String("horizontal"))) { | |
1132 static QMap<QString, Format::HorizontalAlignment> alignStringMap; | |
1133 if (alignStringMap.isEmpty()) { | |
1134 alignStringMap.insert(QStringLiteral("left"), Format::AlignLeft); | |
1135 alignStringMap.insert(QStringLiteral("center"), Format::AlignHCenter); | |
1136 alignStringMap.insert(QStringLiteral("right"), Format::AlignRight); | |
1137 alignStringMap.insert(QStringLiteral("justify"), Format::AlignHJustify); | |
1138 alignStringMap.insert(QStringLiteral("centerContinuous"), Format::AlignHMerge); | |
1139 alignStringMap.insert(QStringLiteral("distributed"), Format::AlignHDistributed); | |
1140 } | |
1141 QString str = alignAttrs.value(QLatin1String("horizontal")).toString(); | |
1142 if (alignStringMap.contains(str)) | |
1143 format.setHorizontalAlignment(alignStringMap[str]); | |
1144 } | |
1145 | |
1146 if (alignAttrs.hasAttribute(QLatin1String("vertical"))) { | |
1147 static QMap<QString, Format::VerticalAlignment> alignStringMap; | |
1148 if (alignStringMap.isEmpty()) { | |
1149 alignStringMap.insert(QStringLiteral("top"), Format::AlignTop); | |
1150 alignStringMap.insert(QStringLiteral("center"), Format::AlignVCenter); | |
1151 alignStringMap.insert(QStringLiteral("justify"), Format::AlignVJustify); | |
1152 alignStringMap.insert(QStringLiteral("distributed"), Format::AlignVDistributed); | |
1153 } | |
1154 QString str = alignAttrs.value(QLatin1String("vertical")).toString(); | |
1155 if (alignStringMap.contains(str)) | |
1156 format.setVerticalAlignment(alignStringMap[str]); | |
1157 } | |
1158 | |
1159 if (alignAttrs.hasAttribute(QLatin1String("indent"))) { | |
1160 int indent = alignAttrs.value(QLatin1String("indent")).toString().toInt(); | |
1161 format.setIndent(indent); | |
1162 } | |
1163 | |
1164 if (alignAttrs.hasAttribute(QLatin1String("textRotation"))) { | |
1165 int rotation = alignAttrs.value(QLatin1String("textRotation")).toString().toInt(); | |
1166 format.setRotation(rotation); | |
1167 } | |
1168 | |
1169 if (alignAttrs.hasAttribute(QLatin1String("wrapText"))) | |
1170 format.setTextWarp(true); | |
1171 | |
1172 if (alignAttrs.hasAttribute(QLatin1String("shrinkToFit"))) | |
1173 format.setShrinkToFit(true); | |
1174 | |
1175 } | |
1176 } | |
1177 | |
1178 addXfFormat(format, true); | |
1179 } | |
1180 } | |
1181 } | |
1182 | |
1183 if (reader.hasError()) | |
1184 qWarning()<<reader.errorString(); | |
1185 | |
1186 if (hasCount && (count != m_xf_formatsList.size())) | |
1187 qWarning("error read CellXfs"); | |
1188 | |
1189 return true; | |
1190 } | |
1191 | |
1192 bool Styles::readDxfs(QXmlStreamReader &reader) | |
1193 { | |
1194 Q_ASSERT(reader.name() == QLatin1String("dxfs")); | |
1195 QXmlStreamAttributes attributes = reader.attributes(); | |
1196 bool hasCount = attributes.hasAttribute(QLatin1String("count")); | |
1197 int count = hasCount ? attributes.value(QLatin1String("count")).toString().toInt() : -1; | |
1198 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement | |
1199 && reader.name() == QLatin1String("dxfs"))) { | |
1200 reader.readNextStartElement(); | |
1201 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
1202 if (reader.name() == QLatin1String("dxf")) | |
1203 readDxf(reader); | |
1204 } | |
1205 } | |
1206 if (reader.hasError()) | |
1207 qWarning()<<reader.errorString(); | |
1208 | |
1209 if (hasCount && (count != m_dxf_formatsList.size())) | |
1210 qWarning("error read dxfs"); | |
1211 | |
1212 return true; | |
1213 } | |
1214 | |
1215 bool Styles::readDxf(QXmlStreamReader &reader) | |
1216 { | |
1217 Q_ASSERT(reader.name() == QLatin1String("dxf")); | |
1218 Format format; | |
1219 while (!reader.atEnd() && !(reader.name() == QLatin1String("dxf") && reader.tokenType() == QXmlStreamReader::EndElement)) { | |
1220 reader.readNextStartElement(); | |
1221 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
1222 if (reader.name() == QLatin1String("numFmt")) { | |
1223 QXmlStreamAttributes attributes = reader.attributes(); | |
1224 int id = attributes.value(QLatin1String("numFmtId")).toString().toInt(); | |
1225 QString code = attributes.value(QLatin1String("formatCode")).toString(); | |
1226 format.setNumberFormat(id, code); | |
1227 } else if (reader.name() == QLatin1String("font")) { | |
1228 readFont(reader, format); | |
1229 } else if (reader.name() == QLatin1String("fill")) { | |
1230 readFill(reader, format); | |
1231 } else if (reader.name() == QLatin1String("border")) { | |
1232 readBorder(reader, format); | |
1233 } | |
1234 } | |
1235 } | |
1236 addDxfFormat(format, true); | |
1237 return true; | |
1238 } | |
1239 | |
1240 bool Styles::readColors(QXmlStreamReader &reader) | |
1241 { | |
1242 Q_ASSERT(reader.name() == QLatin1String("colors")); | |
1243 while (!reader.atEnd() && !(reader.name() == QLatin1String("colors") && reader.tokenType() == QXmlStreamReader::EndElement)) { | |
1244 reader.readNextStartElement(); | |
1245 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
1246 if (reader.name() == QLatin1String("indexedColors")) { | |
1247 readIndexedColors(reader); | |
1248 } else if (reader.name() == QLatin1String("mruColors")) { | |
1249 | |
1250 } | |
1251 } | |
1252 } | |
1253 return true; | |
1254 } | |
1255 | |
1256 bool Styles::readIndexedColors(QXmlStreamReader &reader) | |
1257 { | |
1258 Q_ASSERT(reader.name() == QLatin1String("indexedColors")); | |
1259 m_indexedColors.clear(); | |
1260 while (!reader.atEnd() && !(reader.name() == QLatin1String("indexedColors") && reader.tokenType() == QXmlStreamReader::EndElement)) { | |
1261 reader.readNextStartElement(); | |
1262 if (reader.tokenType() == QXmlStreamReader::StartElement) { | |
1263 if (reader.name() == QLatin1String("rgbColor")) { | |
1264 QString color = reader.attributes().value(QLatin1String("rgb")).toString(); | |
1265 m_indexedColors.append(XlsxColor::fromARGBString(color)); | |
1266 } | |
1267 } | |
1268 } | |
1269 if (!m_indexedColors.isEmpty()) | |
1270 m_isIndexedColorsDefault = false; | |
1271 return true; | |
1272 } | |
1273 | |
1274 bool Styles::loadFromXmlFile(QIODevice *device) | |
1275 { | |
1276 QXmlStreamReader reader(device); | |
1277 while (!reader.atEnd()) { | |
1278 QXmlStreamReader::TokenType token = reader.readNext(); | |
1279 if (token == QXmlStreamReader::StartElement) { | |
1280 if (reader.name() == QLatin1String("numFmts")) { | |
1281 readNumFmts(reader); | |
1282 } else if (reader.name() == QLatin1String("fonts")) { | |
1283 readFonts(reader); | |
1284 } else if (reader.name() == QLatin1String("fills")) { | |
1285 readFills(reader); | |
1286 } else if (reader.name() == QLatin1String("borders")) { | |
1287 readBorders(reader); | |
1288 } else if (reader.name() == QLatin1String("cellStyleXfs")) { | |
1289 | |
1290 } else if (reader.name() == QLatin1String("cellXfs")) { | |
1291 readCellXfs(reader); | |
1292 } else if (reader.name() == QLatin1String("cellStyles")) { | |
1293 | |
1294 } else if (reader.name() == QLatin1String("dxfs")) { | |
1295 readDxfs(reader); | |
1296 } else if (reader.name() == QLatin1String("colors")) { | |
1297 readColors(reader); | |
1298 } | |
1299 } | |
1300 | |
1301 if (reader.hasError()) { | |
1302 qDebug()<<"Error when read style file: "<<reader.errorString(); | |
1303 } | |
1304 } | |
1305 return true; | |
1306 } | |
1307 | |
1308 QColor Styles::getColorByIndex(int idx) | |
1309 { | |
1310 if (m_indexedColors.isEmpty()) { | |
1311 m_indexedColors<<QColor("#000000") <<QColor("#FFFFFF") <<QColor("#FF0000") <<QColor("#00FF00") | |
1312 <<QColor("#0000FF") <<QColor("#FFFF00") <<QColor("#FF00FF") <<QColor("#00FFFF") | |
1313 <<QColor("#000000") <<QColor("#FFFFFF") <<QColor("#FF0000") <<QColor("#00FF00") | |
1314 <<QColor("#0000FF") <<QColor("#FFFF00") <<QColor("#FF00FF") <<QColor("#00FFFF") | |
1315 <<QColor("#800000") <<QColor("#008000") <<QColor("#000080") <<QColor("#808000") | |
1316 <<QColor("#800080") <<QColor("#008080") <<QColor("#C0C0C0") <<QColor("#808080") | |
1317 <<QColor("#9999FF") <<QColor("#993366") <<QColor("#FFFFCC") <<QColor("#CCFFFF") | |
1318 <<QColor("#660066") <<QColor("#FF8080") <<QColor("#0066CC") <<QColor("#CCCCFF") | |
1319 <<QColor("#000080") <<QColor("#FF00FF") <<QColor("#FFFF00") <<QColor("#00FFFF") | |
1320 <<QColor("#800080") <<QColor("#800000") <<QColor("#008080") <<QColor("#0000FF") | |
1321 <<QColor("#00CCFF") <<QColor("#CCFFFF") <<QColor("#CCFFCC") <<QColor("#FFFF99") | |
1322 <<QColor("#99CCFF") <<QColor("#FF99CC") <<QColor("#CC99FF") <<QColor("#FFCC99") | |
1323 <<QColor("#3366FF") <<QColor("#33CCCC") <<QColor("#99CC00") <<QColor("#FFCC00") | |
1324 <<QColor("#FF9900") <<QColor("#FF6600") <<QColor("#666699") <<QColor("#969696") | |
1325 <<QColor("#003366") <<QColor("#339966") <<QColor("#003300") <<QColor("#333300") | |
1326 <<QColor("#993300") <<QColor("#993366") <<QColor("#333399") <<QColor("#333333"); | |
1327 m_isIndexedColorsDefault = true; | |
1328 } | |
1329 if (idx < 0 || idx >= m_indexedColors.size()) | |
1330 return QColor(); | |
1331 return m_indexedColors[idx]; | |
1332 } | |
1333 | |
1334 } //namespace QXlsx |