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
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)