xlsxformat.cpp 29 KB

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