Mercurial > clickerconvert
comparison src/xlsx/xlsxformat.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 "xlsxformat.h" | |
26 #include "xlsxformat_p.h" | |
27 #include "xlsxcolor_p.h" | |
28 #include "xlsxnumformatparser_p.h" | |
29 #include <QDataStream> | |
30 #include <QDebug> | |
31 | |
32 QT_BEGIN_NAMESPACE_XLSX | |
33 | |
34 FormatPrivate::FormatPrivate() | |
35 : dirty(true) | |
36 , font_dirty(true), font_index_valid(false), font_index(0) | |
37 , fill_dirty(true), fill_index_valid(false), fill_index(0) | |
38 , border_dirty(true), border_index_valid(false), border_index(0) | |
39 , xf_index(-1), xf_indexValid(false) | |
40 , is_dxf_fomat(false), dxf_index(-1), dxf_indexValid(false) | |
41 , theme(0) | |
42 { | |
43 } | |
44 | |
45 FormatPrivate::FormatPrivate(const FormatPrivate &other) | |
46 : QSharedData(other) | |
47 , dirty(other.dirty), formatKey(other.formatKey) | |
48 , font_dirty(other.font_dirty), font_index_valid(other.font_index_valid), font_key(other.font_key), font_index(other.font_index) | |
49 , fill_dirty(other.fill_dirty), fill_index_valid(other.fill_index_valid), fill_key(other.fill_key), fill_index(other.fill_index) | |
50 , border_dirty(other.border_dirty), border_index_valid(other.border_index_valid), border_key(other.border_key), border_index(other.border_index) | |
51 , xf_index(other.xf_index), xf_indexValid(other.xf_indexValid) | |
52 , is_dxf_fomat(other.is_dxf_fomat), dxf_index(other.dxf_index), dxf_indexValid(other.dxf_indexValid) | |
53 , theme(other.theme) | |
54 , properties(other.properties) | |
55 { | |
56 | |
57 } | |
58 | |
59 FormatPrivate::~FormatPrivate() | |
60 { | |
61 | |
62 } | |
63 | |
64 /*! | |
65 * \class Format | |
66 * \inmodule QtXlsx | |
67 * \brief Providing the methods and properties that are available for formatting cells in Excel. | |
68 */ | |
69 | |
70 /*! | |
71 * \enum Format::FontScript | |
72 * | |
73 * The enum type defines the type of font script. | |
74 * | |
75 * \value FontScriptNormal normal | |
76 * \value FontScriptSuper super script | |
77 * \value FontScriptSub sub script | |
78 */ | |
79 | |
80 | |
81 /*! | |
82 * \enum Format::FontUnderline | |
83 * | |
84 * The enum type defines the type of font underline. | |
85 * | |
86 * \value FontUnderlineNone | |
87 * \value FontUnderlineSingle | |
88 * \value FontUnderlineDouble | |
89 * \value FontUnderlineSingleAccounting | |
90 * \value FontUnderlineDoubleAccounting | |
91 */ | |
92 | |
93 /*! | |
94 * \enum Format::HorizontalAlignment | |
95 * | |
96 * The enum type defines the type of horizontal alignment. | |
97 * | |
98 * \value AlignHGeneral | |
99 * \value AlignLeft | |
100 * \value AlignHCenter | |
101 * \value AlignRight | |
102 * \value AlignHFill | |
103 * \value AlignHJustify | |
104 * \value AlignHMerge | |
105 * \value AlignHDistributed | |
106 */ | |
107 | |
108 /*! | |
109 * \enum Format::VerticalAlignment | |
110 * | |
111 * The enum type defines the type of vertical alignment. | |
112 * | |
113 * \value AlignTop, | |
114 * \value AlignVCenter, | |
115 * \value AlignBottom, | |
116 * \value AlignVJustify, | |
117 * \value AlignVDistributed | |
118 */ | |
119 | |
120 /*! | |
121 * \enum Format::BorderStyle | |
122 * | |
123 * The enum type defines the type of font underline. | |
124 * | |
125 * \value BorderNone | |
126 * \value BorderThin | |
127 * \value BorderMedium | |
128 * \value BorderDashed | |
129 * \value BorderDotted | |
130 * \value BorderThick | |
131 * \value BorderDouble | |
132 * \value BorderHair | |
133 * \value BorderMediumDashed | |
134 * \value BorderDashDot | |
135 * \value BorderMediumDashDot | |
136 * \value BorderDashDotDot | |
137 * \value BorderMediumDashDotDot | |
138 * \value BorderSlantDashDot | |
139 */ | |
140 | |
141 /*! | |
142 * \enum Format::DiagonalBorderType | |
143 * | |
144 * The enum type defines the type of diagonal border. | |
145 * | |
146 * \value DiagonalBorderNone | |
147 * \value DiagonalBorderDown | |
148 * \value DiagonalBorderUp | |
149 * \value DiagnoalBorderBoth | |
150 */ | |
151 | |
152 /*! | |
153 * \enum Format::FillPattern | |
154 * | |
155 * The enum type defines the type of fill. | |
156 * | |
157 * \value PatternNone | |
158 * \value PatternSolid | |
159 * \value PatternMediumGray | |
160 * \value PatternDarkGray | |
161 * \value PatternLightGray | |
162 * \value PatternDarkHorizontal | |
163 * \value PatternDarkVertical | |
164 * \value PatternDarkDown | |
165 * \value PatternDarkUp | |
166 * \value PatternDarkGrid | |
167 * \value PatternDarkTrellis | |
168 * \value PatternLightHorizontal | |
169 * \value PatternLightVertical | |
170 * \value PatternLightDown | |
171 * \value PatternLightUp | |
172 * \value PatternLightTrellis | |
173 * \value PatternGray125 | |
174 * \value PatternGray0625 | |
175 * \value PatternLightGrid | |
176 */ | |
177 | |
178 /*! | |
179 * Creates a new invalid format. | |
180 */ | |
181 Format::Format() | |
182 { | |
183 //The d pointer is initialized with a null pointer | |
184 } | |
185 | |
186 /*! | |
187 Creates a new format with the same attributes as the \a other format. | |
188 */ | |
189 Format::Format(const Format &other) | |
190 :d(other.d) | |
191 { | |
192 | |
193 } | |
194 | |
195 /*! | |
196 Assigns the \a other format to this format, and returns a | |
197 reference to this format. | |
198 */ | |
199 Format &Format::operator =(const Format &other) | |
200 { | |
201 d = other.d; | |
202 return *this; | |
203 } | |
204 | |
205 /*! | |
206 * Destroys this format. | |
207 */ | |
208 Format::~Format() | |
209 { | |
210 } | |
211 | |
212 /*! | |
213 * Returns the number format identifier. | |
214 */ | |
215 int Format::numberFormatIndex() const | |
216 { | |
217 return intProperty(FormatPrivate::P_NumFmt_Id, 0); | |
218 } | |
219 | |
220 /*! | |
221 * Set the number format identifier. The \a format | |
222 * must be a valid built-in number format identifier | |
223 * or the identifier of a custom number format. | |
224 */ | |
225 void Format::setNumberFormatIndex(int format) | |
226 { | |
227 setProperty(FormatPrivate::P_NumFmt_Id, format); | |
228 clearProperty(FormatPrivate::P_NumFmt_FormatCode); | |
229 } | |
230 | |
231 /*! | |
232 * Returns the number format string. | |
233 * \note for built-in number formats, this may | |
234 * return an empty string. | |
235 */ | |
236 QString Format::numberFormat() const | |
237 { | |
238 return stringProperty(FormatPrivate::P_NumFmt_FormatCode); | |
239 } | |
240 | |
241 /*! | |
242 * Set number \a format. | |
243 * http://office.microsoft.com/en-001/excel-help/create-a-custom-number-format-HP010342372.aspx | |
244 */ | |
245 void Format::setNumberFormat(const QString &format) | |
246 { | |
247 if (format.isEmpty()) | |
248 return; | |
249 setProperty(FormatPrivate::P_NumFmt_FormatCode, format); | |
250 clearProperty(FormatPrivate::P_NumFmt_Id); //numFmt id must be re-generated. | |
251 } | |
252 | |
253 /*! | |
254 * Returns whether the number format is probably a dateTime or not | |
255 */ | |
256 bool Format::isDateTimeFormat() const | |
257 { | |
258 if (hasProperty(FormatPrivate::P_NumFmt_FormatCode)) { | |
259 //Custom numFmt, so | |
260 //Gauss from the number string | |
261 return NumFormatParser::isDateTime(numberFormat()); | |
262 } else if (hasProperty(FormatPrivate::P_NumFmt_Id)){ | |
263 //Non-custom numFmt | |
264 int idx = numberFormatIndex(); | |
265 | |
266 //Is built-in date time number id? | |
267 if ((idx >= 14 && idx <= 22) || (idx >= 45 && idx <= 47)) | |
268 return true; | |
269 | |
270 if ((idx >= 27 && idx <= 36) || (idx >= 50 && idx <= 58)) //Used in CHS\CHT\JPN\KOR | |
271 return true; | |
272 } | |
273 | |
274 return false; | |
275 } | |
276 | |
277 /*! | |
278 \internal | |
279 Set a custom num \a format with the given \a id. | |
280 */ | |
281 void Format::setNumberFormat(int id, const QString &format) | |
282 { | |
283 setProperty(FormatPrivate::P_NumFmt_Id, id); | |
284 setProperty(FormatPrivate::P_NumFmt_FormatCode, format); | |
285 } | |
286 | |
287 /*! | |
288 \internal | |
289 Called by styles to fix the numFmt | |
290 */ | |
291 void Format::fixNumberFormat(int id, const QString &format) | |
292 { | |
293 setProperty(FormatPrivate::P_NumFmt_Id, id, 0, false); | |
294 setProperty(FormatPrivate::P_NumFmt_FormatCode, format, QString(), false); | |
295 } | |
296 | |
297 /*! | |
298 \internal | |
299 Return true if the format has number format. | |
300 */ | |
301 bool Format::hasNumFmtData() const | |
302 { | |
303 if (!d) | |
304 return false; | |
305 | |
306 if (hasProperty(FormatPrivate::P_NumFmt_Id) | |
307 || hasProperty(FormatPrivate::P_NumFmt_FormatCode)) { | |
308 return true; | |
309 } | |
310 return false; | |
311 } | |
312 | |
313 /*! | |
314 * Return the size of the font in points. | |
315 */ | |
316 int Format::fontSize() const | |
317 { | |
318 return intProperty(FormatPrivate::P_Font_Size); | |
319 } | |
320 | |
321 /*! | |
322 * Set the \a size of the font in points. | |
323 */ | |
324 void Format::setFontSize(int size) | |
325 { | |
326 setProperty(FormatPrivate::P_Font_Size, size, 0); | |
327 } | |
328 | |
329 /*! | |
330 * Return whether the font is italic. | |
331 */ | |
332 bool Format::fontItalic() const | |
333 { | |
334 return boolProperty(FormatPrivate::P_Font_Italic); | |
335 } | |
336 | |
337 /*! | |
338 * Turn on/off the italic font based on \a italic. | |
339 */ | |
340 void Format::setFontItalic(bool italic) | |
341 { | |
342 setProperty(FormatPrivate::P_Font_Italic, italic, false); | |
343 } | |
344 | |
345 /*! | |
346 * Return whether the font is strikeout. | |
347 */ | |
348 bool Format::fontStrikeOut() const | |
349 { | |
350 return boolProperty(FormatPrivate::P_Font_StrikeOut); | |
351 } | |
352 | |
353 /*! | |
354 * Turn on/off the strikeOut font based on \a strikeOut. | |
355 */ | |
356 void Format::setFontStrikeOut(bool strikeOut) | |
357 { | |
358 setProperty(FormatPrivate::P_Font_StrikeOut, strikeOut, false); | |
359 } | |
360 | |
361 /*! | |
362 * Return the color of the font. | |
363 */ | |
364 QColor Format::fontColor() const | |
365 { | |
366 if (hasProperty(FormatPrivate::P_Font_Color)) | |
367 return colorProperty(FormatPrivate::P_Font_Color); | |
368 return QColor(); | |
369 } | |
370 | |
371 /*! | |
372 * Set the \a color of the font. | |
373 */ | |
374 void Format::setFontColor(const QColor &color) | |
375 { | |
376 setProperty(FormatPrivate::P_Font_Color, XlsxColor(color), XlsxColor()); | |
377 } | |
378 | |
379 /*! | |
380 * Return whether the font is bold. | |
381 */ | |
382 bool Format::fontBold() const | |
383 { | |
384 return boolProperty(FormatPrivate::P_Font_Bold); | |
385 } | |
386 | |
387 /*! | |
388 * Turn on/off the bold font based on the given \a bold. | |
389 */ | |
390 void Format::setFontBold(bool bold) | |
391 { | |
392 setProperty(FormatPrivate::P_Font_Bold, bold, false); | |
393 } | |
394 | |
395 /*! | |
396 * Return the script style of the font. | |
397 */ | |
398 Format::FontScript Format::fontScript() const | |
399 { | |
400 return static_cast<Format::FontScript>(intProperty(FormatPrivate::P_Font_Script)); | |
401 } | |
402 | |
403 /*! | |
404 * Set the script style of the font to \a script. | |
405 */ | |
406 void Format::setFontScript(FontScript script) | |
407 { | |
408 setProperty(FormatPrivate::P_Font_Script, script, FontScriptNormal); | |
409 } | |
410 | |
411 /*! | |
412 * Return the underline style of the font. | |
413 */ | |
414 Format::FontUnderline Format::fontUnderline() const | |
415 { | |
416 return static_cast<Format::FontUnderline>(intProperty(FormatPrivate::P_Font_Underline)); | |
417 } | |
418 | |
419 /*! | |
420 * Set the underline style of the font to \a underline. | |
421 */ | |
422 void Format::setFontUnderline(FontUnderline underline) | |
423 { | |
424 setProperty(FormatPrivate::P_Font_Underline, underline, FontUnderlineNone); | |
425 } | |
426 | |
427 /*! | |
428 * Return whether the font is outline. | |
429 */ | |
430 bool Format::fontOutline() const | |
431 { | |
432 return boolProperty(FormatPrivate::P_Font_Outline); | |
433 } | |
434 | |
435 /*! | |
436 * Turn on/off the outline font based on \a outline. | |
437 */ | |
438 void Format::setFontOutline(bool outline) | |
439 { | |
440 setProperty(FormatPrivate::P_Font_Outline, outline, false); | |
441 } | |
442 | |
443 /*! | |
444 * Return the name of the font. | |
445 */ | |
446 QString Format::fontName() const | |
447 { | |
448 return stringProperty(FormatPrivate::P_Font_Name, QStringLiteral("Calibri")); | |
449 } | |
450 | |
451 /*! | |
452 * Set the name of the font to \a name. | |
453 */ | |
454 void Format::setFontName(const QString &name) | |
455 { | |
456 setProperty(FormatPrivate::P_Font_Name, name, QStringLiteral("Calibri")); | |
457 } | |
458 | |
459 /*! | |
460 * Returns a QFont object based on font data contained in the format. | |
461 */ | |
462 QFont Format::font() const | |
463 { | |
464 QFont font; | |
465 font.setFamily(fontName()); | |
466 if (fontSize() > 0) | |
467 font.setPointSize(fontSize()); | |
468 font.setBold(fontBold()); | |
469 font.setItalic(fontItalic()); | |
470 font.setUnderline(fontUnderline()!=FontUnderlineNone); | |
471 font.setStrikeOut(fontStrikeOut()); | |
472 return font; | |
473 } | |
474 | |
475 /*! | |
476 * Set the format properties from the given \a font. | |
477 */ | |
478 void Format::setFont(const QFont &font) | |
479 { | |
480 setFontName(font.family()); | |
481 if (font.pointSize() > 0) | |
482 setFontSize(font.pointSize()); | |
483 setFontBold(font.bold()); | |
484 setFontItalic(font.italic()); | |
485 setFontUnderline(font.underline() ? FontUnderlineSingle : FontUnderlineNone); | |
486 setFontStrikeOut(font.strikeOut()); | |
487 } | |
488 | |
489 /*! | |
490 * \internal | |
491 * When the format has font data, when need to assign a valid index for it. | |
492 * The index value is depend on the order <fonts > in styles.xml | |
493 */ | |
494 bool Format::fontIndexValid() const | |
495 { | |
496 if (!hasFontData()) | |
497 return false; | |
498 return d->font_index_valid; | |
499 } | |
500 | |
501 /*! | |
502 * \internal | |
503 */ | |
504 int Format::fontIndex() const | |
505 { | |
506 if (fontIndexValid()) | |
507 return d->font_index; | |
508 | |
509 return 0; | |
510 } | |
511 | |
512 /*! | |
513 * \internal | |
514 */ | |
515 void Format::setFontIndex(int index) | |
516 { | |
517 d->font_index = index; | |
518 d->font_index_valid = true; | |
519 } | |
520 | |
521 /*! | |
522 * \internal | |
523 */ | |
524 QByteArray Format::fontKey() const | |
525 { | |
526 if (isEmpty()) | |
527 return QByteArray(); | |
528 | |
529 if (d->font_dirty) { | |
530 QByteArray key; | |
531 QDataStream stream(&key, QIODevice::WriteOnly); | |
532 for (int i=FormatPrivate::P_Font_STARTID; i<FormatPrivate::P_Font_ENDID; ++i) { | |
533 if (d->properties.contains(i)) | |
534 stream << i << d->properties[i]; | |
535 }; | |
536 | |
537 const_cast<Format*>(this)->d->font_key = key; | |
538 const_cast<Format*>(this)->d->font_dirty = false; | |
539 } | |
540 | |
541 return d->font_key; | |
542 } | |
543 | |
544 /*! | |
545 \internal | |
546 Return true if the format has font format, otherwise return false. | |
547 */ | |
548 bool Format::hasFontData() const | |
549 { | |
550 if (!d) | |
551 return false; | |
552 | |
553 for (int i=FormatPrivate::P_Font_STARTID; i<FormatPrivate::P_Font_ENDID; ++i) { | |
554 if (hasProperty(i)) | |
555 return true; | |
556 } | |
557 return false; | |
558 } | |
559 | |
560 /*! | |
561 * Return the horizontal alignment. | |
562 */ | |
563 Format::HorizontalAlignment Format::horizontalAlignment() const | |
564 { | |
565 return static_cast<Format::HorizontalAlignment>(intProperty(FormatPrivate::P_Alignment_AlignH, AlignHGeneral)); | |
566 } | |
567 | |
568 /*! | |
569 * Set the horizontal alignment with the given \a align. | |
570 */ | |
571 void Format::setHorizontalAlignment(HorizontalAlignment align) | |
572 { | |
573 if (hasProperty(FormatPrivate::P_Alignment_Indent) | |
574 &&(align != AlignHGeneral && align != AlignLeft && align != AlignRight && align != AlignHDistributed)) { | |
575 clearProperty(FormatPrivate::P_Alignment_Indent); | |
576 } | |
577 | |
578 if (hasProperty(FormatPrivate::P_Alignment_ShinkToFit) | |
579 && (align == AlignHFill || align == AlignHJustify || align == AlignHDistributed)) { | |
580 clearProperty(FormatPrivate::P_Alignment_ShinkToFit); | |
581 } | |
582 | |
583 setProperty(FormatPrivate::P_Alignment_AlignH, align, AlignHGeneral); | |
584 } | |
585 | |
586 /*! | |
587 * Return the vertical alignment. | |
588 */ | |
589 Format::VerticalAlignment Format::verticalAlignment() const | |
590 { | |
591 return static_cast<Format::VerticalAlignment>(intProperty(FormatPrivate::P_Alignment_AlignV, AlignBottom)); | |
592 } | |
593 | |
594 /*! | |
595 * Set the vertical alignment with the given \a align. | |
596 */ | |
597 void Format::setVerticalAlignment(VerticalAlignment align) | |
598 { | |
599 setProperty(FormatPrivate::P_Alignment_AlignV, align, AlignBottom); | |
600 } | |
601 | |
602 /*! | |
603 * Return whether the cell text is wrapped. | |
604 */ | |
605 bool Format::textWrap() const | |
606 { | |
607 return boolProperty(FormatPrivate::P_Alignment_Wrap); | |
608 } | |
609 | |
610 /*! | |
611 * Enable the text wrap if \a wrap is true. | |
612 */ | |
613 void Format::setTextWarp(bool wrap) | |
614 { | |
615 if (wrap && hasProperty(FormatPrivate::P_Alignment_ShinkToFit)) | |
616 clearProperty(FormatPrivate::P_Alignment_ShinkToFit); | |
617 | |
618 setProperty(FormatPrivate::P_Alignment_Wrap, wrap, false); | |
619 } | |
620 | |
621 /*! | |
622 * Return the text rotation. | |
623 */ | |
624 int Format::rotation() const | |
625 { | |
626 return intProperty(FormatPrivate::P_Alignment_Rotation); | |
627 } | |
628 | |
629 /*! | |
630 * Set the text roation with the given \a rotation. Must be in the range [0, 180] or 255. | |
631 */ | |
632 void Format::setRotation(int rotation) | |
633 { | |
634 setProperty(FormatPrivate::P_Alignment_Rotation, rotation, 0); | |
635 } | |
636 | |
637 /*! | |
638 * Return the text indentation level. | |
639 */ | |
640 int Format::indent() const | |
641 { | |
642 return intProperty(FormatPrivate::P_Alignment_Indent); | |
643 } | |
644 | |
645 /*! | |
646 * Set the text indentation level with the given \a indent. Must be less than or equal to 15. | |
647 */ | |
648 void Format::setIndent(int indent) | |
649 { | |
650 if (indent && hasProperty(FormatPrivate::P_Alignment_AlignH)) { | |
651 HorizontalAlignment hl = horizontalAlignment(); | |
652 | |
653 if (hl != AlignHGeneral && hl != AlignLeft && hl!= AlignRight && hl!= AlignHJustify) { | |
654 setHorizontalAlignment(AlignLeft); | |
655 } | |
656 } | |
657 | |
658 setProperty(FormatPrivate::P_Alignment_Indent, indent, 0); | |
659 } | |
660 | |
661 /*! | |
662 * Return whether the cell is shrink to fit. | |
663 */ | |
664 bool Format::shrinkToFit() const | |
665 { | |
666 return boolProperty(FormatPrivate::P_Alignment_ShinkToFit); | |
667 } | |
668 | |
669 /*! | |
670 * Turn on/off shrink to fit base on \a shink. | |
671 */ | |
672 void Format::setShrinkToFit(bool shink) | |
673 { | |
674 if (shink && hasProperty(FormatPrivate::P_Alignment_Wrap)) | |
675 clearProperty(FormatPrivate::P_Alignment_Wrap); | |
676 | |
677 if (shink && hasProperty(FormatPrivate::P_Alignment_AlignH)) { | |
678 HorizontalAlignment hl = horizontalAlignment(); | |
679 if (hl == AlignHFill || hl == AlignHJustify || hl == AlignHDistributed) | |
680 setHorizontalAlignment(AlignLeft); | |
681 } | |
682 | |
683 setProperty(FormatPrivate::P_Alignment_ShinkToFit, shink, false); | |
684 } | |
685 | |
686 /*! | |
687 * \internal | |
688 */ | |
689 bool Format::hasAlignmentData() const | |
690 { | |
691 if (!d) | |
692 return false; | |
693 | |
694 for (int i=FormatPrivate::P_Alignment_STARTID; i<FormatPrivate::P_Alignment_ENDID; ++i) { | |
695 if (hasProperty(i)) | |
696 return true; | |
697 } | |
698 return false; | |
699 } | |
700 | |
701 /*! | |
702 * Set the border style with the given \a style. | |
703 */ | |
704 void Format::setBorderStyle(BorderStyle style) | |
705 { | |
706 setLeftBorderStyle(style); | |
707 setRightBorderStyle(style); | |
708 setBottomBorderStyle(style); | |
709 setTopBorderStyle(style); | |
710 } | |
711 | |
712 /*! | |
713 * Sets the border color with the given \a color. | |
714 */ | |
715 void Format::setBorderColor(const QColor &color) | |
716 { | |
717 setLeftBorderColor(color); | |
718 setRightBorderColor(color); | |
719 setTopBorderColor(color); | |
720 setBottomBorderColor(color); | |
721 } | |
722 | |
723 /*! | |
724 * Returns the left border style | |
725 */ | |
726 Format::BorderStyle Format::leftBorderStyle() const | |
727 { | |
728 return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_LeftStyle)); | |
729 } | |
730 | |
731 /*! | |
732 * Sets the left border style to \a style | |
733 */ | |
734 void Format::setLeftBorderStyle(BorderStyle style) | |
735 { | |
736 setProperty(FormatPrivate::P_Border_LeftStyle, style, BorderNone); | |
737 } | |
738 | |
739 /*! | |
740 * Returns the left border color | |
741 */ | |
742 QColor Format::leftBorderColor() const | |
743 { | |
744 return colorProperty(FormatPrivate::P_Border_LeftColor); | |
745 } | |
746 | |
747 /*! | |
748 Sets the left border color to the given \a color | |
749 */ | |
750 void Format::setLeftBorderColor(const QColor &color) | |
751 { | |
752 setProperty(FormatPrivate::P_Border_LeftColor, XlsxColor(color), XlsxColor()); | |
753 } | |
754 | |
755 /*! | |
756 Returns the right border style. | |
757 */ | |
758 Format::BorderStyle Format::rightBorderStyle() const | |
759 { | |
760 return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_RightStyle)); | |
761 } | |
762 | |
763 /*! | |
764 Sets the right border style to the given \a style. | |
765 */ | |
766 void Format::setRightBorderStyle(BorderStyle style) | |
767 { | |
768 setProperty(FormatPrivate::P_Border_RightStyle, style, BorderNone); | |
769 } | |
770 | |
771 /*! | |
772 Returns the right border color. | |
773 */ | |
774 QColor Format::rightBorderColor() const | |
775 { | |
776 return colorProperty(FormatPrivate::P_Border_RightColor); | |
777 } | |
778 | |
779 /*! | |
780 Sets the right border color to the given \a color | |
781 */ | |
782 void Format::setRightBorderColor(const QColor &color) | |
783 { | |
784 setProperty(FormatPrivate::P_Border_RightColor, XlsxColor(color), XlsxColor()); | |
785 } | |
786 | |
787 /*! | |
788 Returns the top border style. | |
789 */ | |
790 Format::BorderStyle Format::topBorderStyle() const | |
791 { | |
792 return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_TopStyle)); | |
793 } | |
794 | |
795 /*! | |
796 Sets the top border style to the given \a style. | |
797 */ | |
798 void Format::setTopBorderStyle(BorderStyle style) | |
799 { | |
800 setProperty(FormatPrivate::P_Border_TopStyle, style, BorderNone); | |
801 } | |
802 | |
803 /*! | |
804 Returns the top border color. | |
805 */ | |
806 QColor Format::topBorderColor() const | |
807 { | |
808 return colorProperty(FormatPrivate::P_Border_TopColor); | |
809 } | |
810 | |
811 /*! | |
812 Sets the top border color to the given \a color. | |
813 */ | |
814 void Format::setTopBorderColor(const QColor &color) | |
815 { | |
816 setProperty(FormatPrivate::P_Border_TopColor, XlsxColor(color), XlsxColor()); | |
817 } | |
818 | |
819 /*! | |
820 Returns the bottom border style. | |
821 */ | |
822 Format::BorderStyle Format::bottomBorderStyle() const | |
823 { | |
824 return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_BottomStyle)); | |
825 } | |
826 | |
827 /*! | |
828 Sets the bottom border style to the given \a style. | |
829 */ | |
830 void Format::setBottomBorderStyle(BorderStyle style) | |
831 { | |
832 setProperty(FormatPrivate::P_Border_BottomStyle, style, BorderNone); | |
833 } | |
834 | |
835 /*! | |
836 Returns the bottom border color. | |
837 */ | |
838 QColor Format::bottomBorderColor() const | |
839 { | |
840 return colorProperty(FormatPrivate::P_Border_BottomColor); | |
841 } | |
842 | |
843 /*! | |
844 Sets the bottom border color to the given \a color. | |
845 */ | |
846 void Format::setBottomBorderColor(const QColor &color) | |
847 { | |
848 setProperty(FormatPrivate::P_Border_BottomColor, XlsxColor(color), XlsxColor()); | |
849 } | |
850 | |
851 /*! | |
852 Return the diagonla border style. | |
853 */ | |
854 Format::BorderStyle Format::diagonalBorderStyle() const | |
855 { | |
856 return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_DiagonalStyle)); | |
857 } | |
858 | |
859 /*! | |
860 Sets the diagonal border style to the given \a style. | |
861 */ | |
862 void Format::setDiagonalBorderStyle(BorderStyle style) | |
863 { | |
864 setProperty(FormatPrivate::P_Border_DiagonalStyle, style, BorderNone); | |
865 } | |
866 | |
867 /*! | |
868 Returns the diagonal border type. | |
869 */ | |
870 Format::DiagonalBorderType Format::diagonalBorderType() const | |
871 { | |
872 return static_cast<DiagonalBorderType>(intProperty(FormatPrivate::P_Border_DiagonalType)); | |
873 } | |
874 | |
875 /*! | |
876 Sets the diagonal border type to the given \a style | |
877 */ | |
878 void Format::setDiagonalBorderType(DiagonalBorderType style) | |
879 { | |
880 setProperty(FormatPrivate::P_Border_DiagonalType, style, DiagonalBorderNone); | |
881 } | |
882 | |
883 /*! | |
884 Returns the diagonal border color. | |
885 */ | |
886 QColor Format::diagonalBorderColor() const | |
887 { | |
888 return colorProperty(FormatPrivate::P_Border_DiagonalColor); | |
889 } | |
890 | |
891 /*! | |
892 Sets the diagonal border color to the given \a color | |
893 */ | |
894 void Format::setDiagonalBorderColor(const QColor &color) | |
895 { | |
896 setProperty(FormatPrivate::P_Border_DiagonalColor, XlsxColor(color), XlsxColor()); | |
897 } | |
898 | |
899 /*! | |
900 \internal | |
901 Returns whether this format has been set valid border index. | |
902 */ | |
903 bool Format::borderIndexValid() const | |
904 { | |
905 if (!hasBorderData()) | |
906 return false; | |
907 return d->border_index_valid; | |
908 } | |
909 | |
910 /*! | |
911 \internal | |
912 Returns the border index. | |
913 */ | |
914 int Format::borderIndex() const | |
915 { | |
916 if (borderIndexValid()) | |
917 return d->border_index; | |
918 return 0; | |
919 } | |
920 | |
921 /*! | |
922 * \internal | |
923 */ | |
924 void Format::setBorderIndex(int index) | |
925 { | |
926 d->border_index = index; | |
927 d->border_index_valid = true; | |
928 } | |
929 | |
930 /*! \internal | |
931 */ | |
932 QByteArray Format::borderKey() const | |
933 { | |
934 if (isEmpty()) | |
935 return QByteArray(); | |
936 | |
937 if (d->border_dirty) { | |
938 QByteArray key; | |
939 QDataStream stream(&key, QIODevice::WriteOnly); | |
940 for (int i=FormatPrivate::P_Border_STARTID; i<FormatPrivate::P_Border_ENDID; ++i) { | |
941 if (d->properties.contains(i)) | |
942 stream << i << d->properties[i]; | |
943 }; | |
944 | |
945 const_cast<Format*>(this)->d->border_key = key; | |
946 const_cast<Format*>(this)->d->border_dirty = false; | |
947 } | |
948 | |
949 return d->border_key; | |
950 } | |
951 | |
952 /*! | |
953 \internal | |
954 Return true if the format has border format, otherwise return false. | |
955 */ | |
956 bool Format::hasBorderData() const | |
957 { | |
958 if (!d) | |
959 return false; | |
960 | |
961 for (int i=FormatPrivate::P_Border_STARTID; i<FormatPrivate::P_Border_ENDID; ++i) { | |
962 if (hasProperty(i)) | |
963 return true; | |
964 } | |
965 return false; | |
966 } | |
967 | |
968 /*! | |
969 Return the fill pattern. | |
970 */ | |
971 Format::FillPattern Format::fillPattern() const | |
972 { | |
973 return static_cast<FillPattern>(intProperty(FormatPrivate::P_Fill_Pattern, PatternNone)); | |
974 } | |
975 | |
976 /*! | |
977 Sets the fill pattern to the given \a pattern. | |
978 */ | |
979 void Format::setFillPattern(FillPattern pattern) | |
980 { | |
981 setProperty(FormatPrivate::P_Fill_Pattern, pattern, PatternNone); | |
982 } | |
983 | |
984 /*! | |
985 Returns the foreground color of the pattern. | |
986 */ | |
987 QColor Format::patternForegroundColor() const | |
988 { | |
989 return colorProperty(FormatPrivate::P_Fill_FgColor); | |
990 } | |
991 | |
992 /*! | |
993 Sets the foreground color of the pattern with the given \a color. | |
994 */ | |
995 void Format::setPatternForegroundColor(const QColor &color) | |
996 { | |
997 if (color.isValid() && !hasProperty(FormatPrivate::P_Fill_Pattern)) | |
998 setFillPattern(PatternSolid); | |
999 setProperty(FormatPrivate::P_Fill_FgColor, XlsxColor(color), XlsxColor()); | |
1000 } | |
1001 | |
1002 /*! | |
1003 Returns the background color of the pattern. | |
1004 */ | |
1005 QColor Format::patternBackgroundColor() const | |
1006 { | |
1007 return colorProperty(FormatPrivate::P_Fill_BgColor); | |
1008 } | |
1009 | |
1010 /*! | |
1011 Sets the background color of the pattern with the given \a color. | |
1012 */ | |
1013 void Format::setPatternBackgroundColor(const QColor &color) | |
1014 { | |
1015 if (color.isValid() && !hasProperty(FormatPrivate::P_Fill_Pattern)) | |
1016 setFillPattern(PatternSolid); | |
1017 setProperty(FormatPrivate::P_Fill_BgColor, XlsxColor(color), XlsxColor()); | |
1018 } | |
1019 | |
1020 /*! | |
1021 * \internal | |
1022 */ | |
1023 bool Format::fillIndexValid() const | |
1024 { | |
1025 if (!hasFillData()) | |
1026 return false; | |
1027 return d->fill_index_valid; | |
1028 } | |
1029 | |
1030 /*! | |
1031 * \internal | |
1032 */ | |
1033 int Format::fillIndex() const | |
1034 { | |
1035 if (fillIndexValid()) | |
1036 return d->fill_index; | |
1037 return 0; | |
1038 } | |
1039 | |
1040 /*! | |
1041 * \internal | |
1042 */ | |
1043 void Format::setFillIndex(int index) | |
1044 { | |
1045 d->fill_index = index; | |
1046 d->fill_index_valid = true; | |
1047 } | |
1048 | |
1049 /*! | |
1050 * \internal | |
1051 */ | |
1052 QByteArray Format::fillKey() const | |
1053 { | |
1054 if (isEmpty()) | |
1055 return QByteArray(); | |
1056 | |
1057 if (d->fill_dirty) { | |
1058 QByteArray key; | |
1059 QDataStream stream(&key, QIODevice::WriteOnly); | |
1060 for (int i=FormatPrivate::P_Fill_STARTID; i<FormatPrivate::P_Fill_ENDID; ++i) { | |
1061 if (d->properties.contains(i)) | |
1062 stream << i << d->properties[i]; | |
1063 }; | |
1064 | |
1065 const_cast<Format*>(this)->d->fill_key = key; | |
1066 const_cast<Format*>(this)->d->fill_dirty = false; | |
1067 } | |
1068 | |
1069 return d->fill_key; | |
1070 } | |
1071 | |
1072 /*! | |
1073 \internal | |
1074 Return true if the format has fill format, otherwise return false. | |
1075 */ | |
1076 bool Format::hasFillData() const | |
1077 { | |
1078 if (!d) | |
1079 return false; | |
1080 | |
1081 for (int i=FormatPrivate::P_Fill_STARTID; i<FormatPrivate::P_Fill_ENDID; ++i) { | |
1082 if (hasProperty(i)) | |
1083 return true; | |
1084 } | |
1085 return false; | |
1086 } | |
1087 | |
1088 /*! | |
1089 Returns whether the hidden protection property is set to true. | |
1090 */ | |
1091 bool Format::hidden() const | |
1092 { | |
1093 return boolProperty(FormatPrivate::P_Protection_Hidden); | |
1094 } | |
1095 | |
1096 /*! | |
1097 Sets the hidden protection property with the given \a hidden. | |
1098 */ | |
1099 void Format::setHidden(bool hidden) | |
1100 { | |
1101 setProperty(FormatPrivate::P_Protection_Hidden, hidden); | |
1102 } | |
1103 | |
1104 /*! | |
1105 Returns whether the locked protection property is set to true. | |
1106 */ | |
1107 bool Format::locked() const | |
1108 { | |
1109 return boolProperty(FormatPrivate::P_Protection_Locked); | |
1110 } | |
1111 | |
1112 /*! | |
1113 Sets the locked protection property with the given \a locked. | |
1114 */ | |
1115 void Format::setLocked(bool locked) | |
1116 { | |
1117 setProperty(FormatPrivate::P_Protection_Locked, locked); | |
1118 } | |
1119 | |
1120 /*! | |
1121 \internal | |
1122 Return true if the format has protection data, otherwise return false. | |
1123 */ | |
1124 bool Format::hasProtectionData() const | |
1125 { | |
1126 if (!d) | |
1127 return false; | |
1128 | |
1129 if (hasProperty(FormatPrivate::P_Protection_Hidden | |
1130 || FormatPrivate::P_Protection_Locked)) { | |
1131 return true; | |
1132 } | |
1133 return false; | |
1134 } | |
1135 | |
1136 /*! | |
1137 Merges the current format with the properties described by format \a modifier. | |
1138 */ | |
1139 void Format::mergeFormat(const Format &modifier) | |
1140 { | |
1141 if (!modifier.isValid()) | |
1142 return; | |
1143 | |
1144 if (!isValid()) { | |
1145 d = modifier.d; | |
1146 return; | |
1147 } | |
1148 | |
1149 QMapIterator<int, QVariant> it(modifier.d->properties); | |
1150 while(it.hasNext()) { | |
1151 it.next(); | |
1152 setProperty(it.key(), it.value()); | |
1153 } | |
1154 } | |
1155 | |
1156 /*! | |
1157 Returns true if the format is valid; otherwise returns false. | |
1158 */ | |
1159 bool Format::isValid() const | |
1160 { | |
1161 if (d) | |
1162 return true; | |
1163 return false; | |
1164 } | |
1165 | |
1166 /*! | |
1167 Returns true if the format is empty; otherwise returns false. | |
1168 */ | |
1169 bool Format::isEmpty() const | |
1170 { | |
1171 if (!d) | |
1172 return true; | |
1173 return d->properties.isEmpty(); | |
1174 } | |
1175 | |
1176 /*! | |
1177 * \internal | |
1178 */ | |
1179 QByteArray Format::formatKey() const | |
1180 { | |
1181 if (isEmpty()) | |
1182 return QByteArray(); | |
1183 | |
1184 if (d->dirty) { | |
1185 QByteArray key; | |
1186 QDataStream stream(&key, QIODevice::WriteOnly); | |
1187 | |
1188 QMapIterator<int, QVariant> i(d->properties); | |
1189 while (i.hasNext()) { | |
1190 i.next(); | |
1191 stream<<i.key()<<i.value(); | |
1192 } | |
1193 | |
1194 d->formatKey = key; | |
1195 d->dirty = false; | |
1196 } | |
1197 | |
1198 return d->formatKey; | |
1199 } | |
1200 | |
1201 /*! | |
1202 * \internal | |
1203 * Called by QXlsx::Styles or some unittests. | |
1204 */ | |
1205 void Format::setXfIndex(int index) | |
1206 { | |
1207 if (!d) | |
1208 d = new FormatPrivate; | |
1209 d->xf_index = index; | |
1210 d->xf_indexValid = true; | |
1211 } | |
1212 | |
1213 /*! | |
1214 * \internal | |
1215 */ | |
1216 int Format::xfIndex() const | |
1217 { | |
1218 if (!d) | |
1219 return -1; | |
1220 return d->xf_index; | |
1221 } | |
1222 | |
1223 /*! | |
1224 * \internal | |
1225 */ | |
1226 bool Format::xfIndexValid() const | |
1227 { | |
1228 if (!d) | |
1229 return false; | |
1230 return d->xf_indexValid; | |
1231 } | |
1232 | |
1233 /*! | |
1234 * \internal | |
1235 * Called by QXlsx::Styles or some unittests. | |
1236 */ | |
1237 void Format::setDxfIndex(int index) | |
1238 { | |
1239 if (!d) | |
1240 d = new FormatPrivate; | |
1241 d->dxf_index = index; | |
1242 d->dxf_indexValid = true; | |
1243 } | |
1244 | |
1245 /*! | |
1246 * \internal | |
1247 * Returns the index in the styles dxfs. | |
1248 */ | |
1249 int Format::dxfIndex() const | |
1250 { | |
1251 if (!d) | |
1252 return -1; | |
1253 return d->dxf_index; | |
1254 } | |
1255 | |
1256 /*! | |
1257 * \internal | |
1258 * Returns whether the dxf index is valid or not. | |
1259 */ | |
1260 bool Format::dxfIndexValid() const | |
1261 { | |
1262 if (!d) | |
1263 return false; | |
1264 return d->dxf_indexValid; | |
1265 } | |
1266 | |
1267 /*! | |
1268 Returns ture if the \a format is equal to this format. | |
1269 */ | |
1270 bool Format::operator ==(const Format &format) const | |
1271 { | |
1272 return this->formatKey() == format.formatKey(); | |
1273 } | |
1274 | |
1275 /*! | |
1276 Returns ture if the \a format is not equal to this format. | |
1277 */ | |
1278 bool Format::operator !=(const Format &format) const | |
1279 { | |
1280 return this->formatKey() != format.formatKey(); | |
1281 } | |
1282 | |
1283 int Format::theme() const | |
1284 { | |
1285 return d->theme; | |
1286 } | |
1287 | |
1288 /*! | |
1289 * \internal | |
1290 */ | |
1291 QVariant Format::property(int propertyId, const QVariant &defaultValue) const | |
1292 { | |
1293 if (d && d->properties.contains(propertyId)) | |
1294 return d->properties[propertyId]; | |
1295 return defaultValue; | |
1296 } | |
1297 | |
1298 /*! | |
1299 * \internal | |
1300 */ | |
1301 void Format::setProperty(int propertyId, const QVariant &value, const QVariant &clearValue, bool detach) | |
1302 { | |
1303 if (!d) | |
1304 d = new FormatPrivate; | |
1305 | |
1306 if (value != clearValue) { | |
1307 if (d->properties.contains(propertyId) && d->properties[propertyId] == value) | |
1308 return; | |
1309 if (detach) | |
1310 d.detach(); | |
1311 d->properties[propertyId] = value; | |
1312 } else { | |
1313 if (!d->properties.contains(propertyId)) | |
1314 return; | |
1315 if (detach) | |
1316 d.detach(); | |
1317 d->properties.remove(propertyId); | |
1318 } | |
1319 | |
1320 d->dirty = true; | |
1321 d->xf_indexValid = false; | |
1322 d->dxf_indexValid = false; | |
1323 | |
1324 if (propertyId >= FormatPrivate::P_Font_STARTID && propertyId < FormatPrivate::P_Font_ENDID) { | |
1325 d->font_dirty = true; | |
1326 d->font_index_valid = false; | |
1327 } else if (propertyId >= FormatPrivate::P_Border_STARTID && propertyId < FormatPrivate::P_Border_ENDID) { | |
1328 d->border_dirty = true; | |
1329 d->border_index_valid = false; | |
1330 } else if (propertyId >= FormatPrivate::P_Fill_STARTID && propertyId < FormatPrivate::P_Fill_ENDID) { | |
1331 d->fill_dirty = true; | |
1332 d->fill_index_valid = false; | |
1333 } | |
1334 } | |
1335 | |
1336 /*! | |
1337 * \internal | |
1338 */ | |
1339 void Format::clearProperty(int propertyId) | |
1340 { | |
1341 setProperty(propertyId, QVariant()); | |
1342 } | |
1343 | |
1344 /*! | |
1345 * \internal | |
1346 */ | |
1347 bool Format::hasProperty(int propertyId) const | |
1348 { | |
1349 if (!d) | |
1350 return false; | |
1351 return d->properties.contains(propertyId); | |
1352 } | |
1353 | |
1354 /*! | |
1355 * \internal | |
1356 */ | |
1357 bool Format::boolProperty(int propertyId, bool defaultValue) const | |
1358 { | |
1359 if (!hasProperty(propertyId)) | |
1360 return defaultValue; | |
1361 | |
1362 const QVariant prop = d->properties[propertyId]; | |
1363 if (prop.userType() != QMetaType::Bool) | |
1364 return defaultValue; | |
1365 return prop.toBool(); | |
1366 } | |
1367 | |
1368 /*! | |
1369 * \internal | |
1370 */ | |
1371 int Format::intProperty(int propertyId, int defaultValue) const | |
1372 { | |
1373 if (!hasProperty(propertyId)) | |
1374 return defaultValue; | |
1375 | |
1376 const QVariant prop = d->properties[propertyId]; | |
1377 if (prop.userType() != QMetaType::Int) | |
1378 return defaultValue; | |
1379 return prop.toInt(); | |
1380 } | |
1381 | |
1382 /*! | |
1383 * \internal | |
1384 */ | |
1385 double Format::doubleProperty(int propertyId, double defaultValue) const | |
1386 { | |
1387 if (!hasProperty(propertyId)) | |
1388 return defaultValue; | |
1389 | |
1390 const QVariant prop = d->properties[propertyId]; | |
1391 if (prop.userType() != QMetaType::Double && prop.userType() != QMetaType::Float) | |
1392 return defaultValue; | |
1393 return prop.toDouble(); | |
1394 } | |
1395 | |
1396 /*! | |
1397 * \internal | |
1398 */ | |
1399 QString Format::stringProperty(int propertyId, const QString &defaultValue) const | |
1400 { | |
1401 if (!hasProperty(propertyId)) | |
1402 return defaultValue; | |
1403 | |
1404 const QVariant prop = d->properties[propertyId]; | |
1405 if (prop.userType() != QMetaType::QString) | |
1406 return defaultValue; | |
1407 return prop.toString(); | |
1408 } | |
1409 | |
1410 /*! | |
1411 * \internal | |
1412 */ | |
1413 QColor Format::colorProperty(int propertyId, const QColor &defaultValue) const | |
1414 { | |
1415 if (!hasProperty(propertyId)) | |
1416 return defaultValue; | |
1417 | |
1418 const QVariant prop = d->properties[propertyId]; | |
1419 if (prop.userType() != qMetaTypeId<XlsxColor>()) | |
1420 return defaultValue; | |
1421 return qvariant_cast<XlsxColor>(prop).rgbColor(); | |
1422 } | |
1423 | |
1424 #ifndef QT_NO_DEBUG_STREAM | |
1425 QDebug operator<<(QDebug dbg, const Format &f) | |
1426 { | |
1427 dbg.nospace() << "QXlsx::Format(" << f.d->properties << ")"; | |
1428 return dbg.space(); | |
1429 } | |
1430 #endif | |
1431 | |
1432 QT_END_NAMESPACE_XLSX |