1 /* This file is part of the KDE project
2  * Copyright (C) 2006-2009 Thomas Zander <zander@kde.org>
3  * Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org>
4  * Copyright (C) 2008 Roopesh Chander <roop@forwardbias.in>
5  * Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in>
6  * Copyright (C) 2009 KO GmbH <cbo@kogmbh.com>
7  * Copyright (C) 2011 Pierre Ducroquet <pinaraf@pinaraf.info>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 #include "KoTableStyle.h"
25 
26 #include <KoGenStyle.h>
27 #include "Styles_p.h"
28 
29 #include <QTextTable>
30 #include <QTextTableFormat>
31 
32 #include <KoShadowStyle.h>
33 #include <KoUnit.h>
34 #include <KoStyleStack.h>
35 #include <KoOdfLoadingContext.h>
36 #include <KoXmlNS.h>
37 #include <KoXmlReader.h>
38 
39 #include "TextDebug.h"
40 
41 class Q_DECL_HIDDEN KoTableStyle::Private
42 {
43 public:
Private()44     Private() : parentStyle(0), next(0) {}
45 
~Private()46     ~Private() {
47     }
48 
setProperty(int key,const QVariant & value)49     void setProperty(int key, const QVariant &value) {
50         stylesPrivate.add(key, value);
51     }
52 
53     QString name;
54     KoTableStyle *parentStyle;
55     int next;
56     StylePrivate stylesPrivate;
57 };
58 
KoTableStyle(QObject * parent)59 KoTableStyle::KoTableStyle(QObject *parent)
60         : QObject(parent), d(new Private())
61 {
62 }
63 
KoTableStyle(const QTextTableFormat & tableFormat,QObject * parent)64 KoTableStyle::KoTableStyle(const QTextTableFormat &tableFormat, QObject *parent)
65         : QObject(parent),
66         d(new Private())
67 {
68     d->stylesPrivate = tableFormat.properties();
69 }
70 
fromTable(const QTextTable & table,QObject * parent)71 KoTableStyle *KoTableStyle::fromTable(const QTextTable &table, QObject *parent)
72 {
73     QTextTableFormat tableFormat = table.format();
74     return new KoTableStyle(tableFormat, parent);
75 }
76 
~KoTableStyle()77 KoTableStyle::~KoTableStyle()
78 {
79     delete d;
80 }
81 
setParentStyle(KoTableStyle * parent)82 void KoTableStyle::setParentStyle(KoTableStyle *parent)
83 {
84     d->parentStyle = parent;
85 }
86 
setProperty(int key,const QVariant & value)87 void KoTableStyle::setProperty(int key, const QVariant &value)
88 {
89     if (d->parentStyle) {
90         QVariant var = d->parentStyle->value(key);
91         if (!var.isNull() && var == value) { // same as parent, so its actually a reset.
92             d->stylesPrivate.remove(key);
93             return;
94         }
95     }
96     d->stylesPrivate.add(key, value);
97 }
98 
remove(int key)99 void KoTableStyle::remove(int key)
100 {
101     d->stylesPrivate.remove(key);
102 }
103 
value(int key) const104 QVariant KoTableStyle::value(int key) const
105 {
106     QVariant var = d->stylesPrivate.value(key);
107     if (var.isNull() && d->parentStyle)
108         return d->parentStyle->value(key);
109     return var;
110 }
111 
hasProperty(int key) const112 bool KoTableStyle::hasProperty(int key) const
113 {
114     return d->stylesPrivate.contains(key);
115 }
116 
propertyDouble(int key) const117 qreal KoTableStyle::propertyDouble(int key) const
118 {
119     QVariant variant = value(key);
120     if (variant.isNull())
121         return 0.0;
122     return variant.toDouble();
123 }
124 
propertyLength(int key) const125 QTextLength KoTableStyle::propertyLength(int key) const
126 {
127     QVariant variant = value(key);
128     if (variant.isNull())
129         return QTextLength(QTextLength::FixedLength, 0.0);
130     if (!variant.canConvert<QTextLength>())
131     {
132         // Fake support, for compatibility sake
133         if (variant.canConvert<qreal>())
134         {
135             return QTextLength(QTextLength::FixedLength, variant.toReal());
136         }
137 
138         warnText << "This should never happen : requested property can't be converted to QTextLength";
139         return QTextLength(QTextLength::FixedLength, 0.0);
140     }
141     return variant.value<QTextLength>();
142 }
143 
propertyInt(int key) const144 int KoTableStyle::propertyInt(int key) const
145 {
146     QVariant variant = value(key);
147     if (variant.isNull())
148         return 0;
149     return variant.toInt();
150 }
151 
propertyBoolean(int key) const152 bool KoTableStyle::propertyBoolean(int key) const
153 {
154     QVariant variant = value(key);
155     if (variant.isNull())
156         return false;
157     return variant.toBool();
158 }
159 
propertyColor(int key) const160 QColor KoTableStyle::propertyColor(int key) const
161 {
162     QVariant variant = value(key);
163     if (variant.isNull()) {
164         return QColor();
165     }
166     return qvariant_cast<QColor>(variant);
167 }
168 
applyStyle(QTextTableFormat & format) const169 void KoTableStyle::applyStyle(QTextTableFormat &format) const
170 {/*
171     if (d->parentStyle) {
172         d->parentStyle->applyStyle(format);
173     }*/
174     QList<int> keys = d->stylesPrivate.keys();
175     for (int i = 0; i < keys.count(); i++) {
176         QVariant variant = d->stylesPrivate.value(keys[i]);
177         int key = keys[i];
178         switch(key) {
179             // Qt expects qreal's for the Frame*Margin's unlike the Block*Margin's
180             case QTextFormat::FrameTopMargin:
181             case QTextFormat::FrameBottomMargin:
182             case QTextFormat::FrameLeftMargin:
183             case QTextFormat::FrameRightMargin:
184                 variant = propertyLength(key).rawValue();
185                 break;
186             default:
187                 break;
188         }
189         format.setProperty(key, variant);
190     }
191 }
192 
setWidth(const QTextLength & width)193 void KoTableStyle::setWidth(const QTextLength &width)
194 {
195     d->setProperty(QTextFormat::FrameWidth, width);
196 }
197 
setKeepWithNext(bool keep)198 void KoTableStyle::setKeepWithNext(bool keep)
199 {
200     d->setProperty(KeepWithNext, keep);
201 }
202 
keepWithNext() const203 bool KoTableStyle::keepWithNext() const
204 {
205     return propertyBoolean(KeepWithNext);
206 }
207 
setShadow(const KoShadowStyle & shadow)208 void KoTableStyle::setShadow(const KoShadowStyle &shadow)
209 {
210     d->setProperty(Shadow, QVariant::fromValue<KoShadowStyle>(shadow));
211 }
212 
shadow() const213 KoShadowStyle KoTableStyle::shadow() const
214 {
215     if (hasProperty(Shadow))
216         return value(Shadow).value<KoShadowStyle>();
217     return KoShadowStyle();
218 }
219 
setMayBreakBetweenRows(bool allow)220 void KoTableStyle::setMayBreakBetweenRows(bool allow)
221 {
222     d->setProperty(MayBreakBetweenRows, allow);
223 }
224 
setBackground(const QBrush & brush)225 void KoTableStyle::setBackground(const QBrush &brush)
226 {
227     d->setProperty(QTextFormat::BackgroundBrush, brush);
228 }
229 
clearBackground()230 void KoTableStyle::clearBackground()
231 {
232     d->stylesPrivate.remove(QTextCharFormat::BackgroundBrush);
233 }
234 
background() const235 QBrush KoTableStyle::background() const
236 {
237     QVariant variant = d->stylesPrivate.value(QTextFormat::BackgroundBrush);
238 
239     if (variant.isNull()) {
240         return QBrush();
241     }
242     return qvariant_cast<QBrush>(variant);
243 }
244 
setBreakBefore(KoText::KoTextBreakProperty state)245 void KoTableStyle::setBreakBefore(KoText::KoTextBreakProperty state)
246 {
247     setProperty(BreakBefore, state);
248 }
249 
breakBefore() const250 KoText::KoTextBreakProperty KoTableStyle::breakBefore() const
251 {
252     return (KoText::KoTextBreakProperty) propertyInt(BreakBefore);
253 }
254 
setBreakAfter(KoText::KoTextBreakProperty state)255 void KoTableStyle::setBreakAfter(KoText::KoTextBreakProperty state)
256 {
257     setProperty(BreakAfter, state);
258 }
259 
breakAfter() const260 KoText::KoTextBreakProperty KoTableStyle::breakAfter() const
261 {
262     return (KoText::KoTextBreakProperty) propertyInt(BreakAfter);
263 }
264 
setCollapsingBorderModel(bool on)265 void KoTableStyle::setCollapsingBorderModel(bool on)
266 {
267     setProperty(CollapsingBorders, on);
268 }
269 
collapsingBorderModel() const270 bool KoTableStyle::collapsingBorderModel() const
271 {
272     return propertyBoolean(CollapsingBorders);
273 }
274 
setTopMargin(QTextLength topMargin)275 void KoTableStyle::setTopMargin(QTextLength topMargin)
276 {
277     setProperty(QTextFormat::FrameTopMargin, topMargin);
278 }
279 
topMargin() const280 qreal KoTableStyle::topMargin() const
281 {
282     if (parentStyle())
283         return propertyLength(QTextFormat::FrameTopMargin).value(parentStyle()->topMargin());
284     else
285         return propertyLength(QTextFormat::FrameTopMargin).value(0);
286 }
287 
setBottomMargin(QTextLength margin)288 void KoTableStyle::setBottomMargin(QTextLength margin)
289 {
290     setProperty(QTextFormat::FrameBottomMargin, margin);
291 }
292 
bottomMargin() const293 qreal KoTableStyle::bottomMargin() const
294 {
295     if (parentStyle())
296         return propertyLength(QTextFormat::FrameBottomMargin).value(parentStyle()->bottomMargin());
297     else
298         return propertyLength(QTextFormat::FrameBottomMargin).value(0);
299 }
300 
setLeftMargin(QTextLength margin)301 void KoTableStyle::setLeftMargin(QTextLength margin)
302 {
303     setProperty(QTextFormat::FrameLeftMargin, margin);
304 }
305 
leftMargin() const306 qreal KoTableStyle::leftMargin() const
307 {
308     if (parentStyle())
309         return propertyLength(QTextFormat::FrameLeftMargin).value(parentStyle()->leftMargin());
310     else
311         return propertyLength(QTextFormat::FrameLeftMargin).value(0);
312 }
313 
setRightMargin(QTextLength margin)314 void KoTableStyle::setRightMargin(QTextLength margin)
315 {
316     setProperty(QTextFormat::FrameRightMargin, margin);
317 }
318 
rightMargin() const319 qreal KoTableStyle::rightMargin() const
320 {
321     if (parentStyle())
322         return propertyLength(QTextFormat::FrameRightMargin).value(parentStyle()->rightMargin());
323     else
324         return propertyLength(QTextFormat::FrameRightMargin).value(0);
325 }
326 
setMargin(QTextLength margin)327 void KoTableStyle::setMargin(QTextLength margin)
328 {
329     setTopMargin(margin);
330     setBottomMargin(margin);
331     setLeftMargin(margin);
332     setRightMargin(margin);
333 }
334 
setAlignment(Qt::Alignment alignment)335 void KoTableStyle::setAlignment(Qt::Alignment alignment)
336 {
337     setProperty(QTextFormat::BlockAlignment, (int) alignment);
338 }
339 
alignment() const340 Qt::Alignment KoTableStyle::alignment() const
341 {
342     return static_cast<Qt::Alignment>(propertyInt(QTextFormat::BlockAlignment));
343 }
344 
parentStyle() const345 KoTableStyle *KoTableStyle::parentStyle() const
346 {
347     return d->parentStyle;
348 }
349 
name() const350 QString KoTableStyle::name() const
351 {
352     return d->name;
353 }
354 
setName(const QString & name)355 void KoTableStyle::setName(const QString &name)
356 {
357     if (name == d->name)
358         return;
359     d->name = name;
360     emit nameChanged(name);
361 }
362 
styleId() const363 int KoTableStyle::styleId() const
364 {
365     return propertyInt(StyleId);
366 }
367 
setStyleId(int id)368 void KoTableStyle::setStyleId(int id)
369 {
370     setProperty(StyleId, id); if (d->next == 0) d->next = id;
371 }
372 
masterPageName() const373 QString KoTableStyle::masterPageName() const
374 {
375     return value(MasterPageName).toString();
376 }
377 
setMasterPageName(const QString & name)378 void KoTableStyle::setMasterPageName(const QString &name)
379 {
380     setProperty(MasterPageName, name);
381 }
382 
alignmentFromString(const QString & align)383 Qt::Alignment KoTableStyle::alignmentFromString(const QString &align)
384 {
385     Qt::Alignment alignment = Qt::AlignLeft;
386     if (align == "left")
387         alignment = Qt::AlignLeft;
388     else if (align == "right")
389         alignment = Qt::AlignRight;
390     else if (align == "center")
391         alignment = Qt::AlignHCenter;
392     else if (align == "margins") // in tables this is effectively the same as justify
393         alignment = Qt::AlignJustify;
394     return alignment;
395 }
396 
alignmentToString(Qt::Alignment alignment)397 QString KoTableStyle::alignmentToString(Qt::Alignment alignment)
398 {
399     QString align;
400     if (alignment == Qt::AlignLeft)
401         align = "left";
402     else if (alignment == Qt::AlignRight)
403         align = "right";
404     else if (alignment == Qt::AlignHCenter)
405         align = "center";
406     else if (alignment == Qt::AlignJustify)
407         align = "margins";
408     return align;
409 }
410 
mayBreakBetweenRows() const411 bool KoTableStyle::mayBreakBetweenRows() const
412 {
413     return propertyBoolean(MayBreakBetweenRows);
414 }
415 
setPageNumber(int page)416 void KoTableStyle::setPageNumber(int page)
417 {
418     if (page >= 0)
419         setProperty(PageNumber, page);
420 }
421 
pageNumber() const422 int KoTableStyle::pageNumber() const
423 {
424     return propertyInt(PageNumber);
425 }
426 
visible() const427 bool KoTableStyle::visible() const
428 {
429     if (hasProperty(Visible))
430         return propertyBoolean(Visible);
431     return true;
432 }
433 
setVisible(bool on)434 void KoTableStyle::setVisible(bool on)
435 {
436     setProperty(Visible, on);
437 }
438 
textDirection() const439 KoText::Direction KoTableStyle::textDirection() const
440 {
441     return (KoText::Direction) propertyInt(TextProgressionDirection);
442 }
443 
setTextDirection(KoText::Direction direction)444 void KoTableStyle::setTextDirection(KoText::Direction direction)
445 {
446     setProperty(TextProgressionDirection, direction);
447 }
448 
loadOdf(const KoXmlElement * element,KoOdfLoadingContext & context)449 void KoTableStyle::loadOdf(const KoXmlElement *element, KoOdfLoadingContext &context)
450 {
451     if (element->hasAttributeNS(KoXmlNS::style, "display-name"))
452         d->name = element->attributeNS(KoXmlNS::style, "display-name", QString());
453 
454     if (d->name.isEmpty()) // if no style:display-name is given us the style:name
455         d->name = element->attributeNS(KoXmlNS::style, "name", QString());
456 
457     QString masterPage = element->attributeNS(KoXmlNS::style, "master-page-name", QString());
458     if (! masterPage.isEmpty()) {
459         setMasterPageName(masterPage);
460     }
461     context.styleStack().save();
462     QString family = element->attributeNS(KoXmlNS::style, "family", "table");
463     context.addStyles(element, family.toLocal8Bit().constData());   // Load all parents - only because we don't support inheritance.
464 
465     context.styleStack().setTypeProperties("table");   // load all style attributes from "style:table-properties"
466     loadOdfProperties(context.styleStack());   // load the KoTableStyle from the stylestack
467     context.styleStack().restore();
468 }
469 
loadOdfProperties(KoStyleStack & styleStack)470 void KoTableStyle::loadOdfProperties(KoStyleStack &styleStack)
471 {
472     if (styleStack.hasProperty(KoXmlNS::style, "writing-mode")) {     // http://www.w3.org/TR/2004/WD-xsl11-20041216/#writing-mode
473         setTextDirection(KoText::directionFromString(styleStack.property(KoXmlNS::style, "writing-mode")));
474     }
475 
476     if (styleStack.hasProperty(KoXmlNS::table, "display")) {
477         setVisible(styleStack.property(KoXmlNS::table, "display") == "true");
478     }
479 
480     // Width
481     if (styleStack.hasProperty(KoXmlNS::style, "width")) {
482         setWidth(QTextLength(QTextLength::FixedLength, KoUnit::parseValue(styleStack.property(KoXmlNS::style, "width"))));
483     }
484     if (styleStack.hasProperty(KoXmlNS::style, "rel-width")) {
485         setWidth(QTextLength(QTextLength::PercentageLength, styleStack.property(KoXmlNS::style, "rel-width").remove('%').remove('*').toDouble()));
486     }
487 
488     // Alignment
489     if (styleStack.hasProperty(KoXmlNS::table, "align")) {
490         setAlignment(alignmentFromString(styleStack.property(KoXmlNS::table, "align")));
491     }
492 
493     // Margin
494     bool hasMarginLeft = styleStack.hasProperty(KoXmlNS::fo, "margin-left");
495     bool hasMarginRight = styleStack.hasProperty(KoXmlNS::fo, "margin-right");
496     if (hasMarginLeft)
497         setLeftMargin(KoText::parseLength(styleStack.property(KoXmlNS::fo, "margin-left")));
498     if (hasMarginRight)
499         setRightMargin(KoText::parseLength(styleStack.property(KoXmlNS::fo, "margin-right")));
500     if (styleStack.hasProperty(KoXmlNS::fo, "margin-top"))
501         setTopMargin(KoText::parseLength(styleStack.property(KoXmlNS::fo, "margin-top")));
502     if (styleStack.hasProperty(KoXmlNS::fo, "margin-bottom"))
503         setBottomMargin(KoText::parseLength(styleStack.property(KoXmlNS::fo, "margin-bottom")));
504     if (styleStack.hasProperty(KoXmlNS::fo, "margin")) {
505         setMargin(KoText::parseLength(styleStack.property(KoXmlNS::fo, "margin")));
506     }
507 
508     // keep table with next paragraph?
509     if (styleStack.hasProperty(KoXmlNS::fo, "keep-with-next")) {
510         // OASIS spec says it's "auto"/"always", not a boolean.
511         QString val = styleStack.property(KoXmlNS::fo, "keep-with-next");
512         setKeepWithNext(val == "true" || val == "always");
513     }
514 
515     // The fo:break-before and fo:break-after attributes insert a page or column break before or after a table.
516     if (styleStack.hasProperty(KoXmlNS::fo, "break-before")) {
517         setBreakBefore(KoText::textBreakFromString(styleStack.property(KoXmlNS::fo, "break-before")));
518     }
519     if (styleStack.hasProperty(KoXmlNS::fo, "break-after")) {
520         setBreakAfter(KoText::textBreakFromString(styleStack.property(KoXmlNS::fo, "break-after")));
521     }
522 
523     if (styleStack.hasProperty(KoXmlNS::style, "may-break-between-rows")) {
524         setMayBreakBetweenRows(styleStack.property(KoXmlNS::style, "may-break-between-rows") == "true");
525     }
526 
527     if (styleStack.hasProperty(KoXmlNS::style, "page-number")) {
528         setPageNumber(styleStack.property(KoXmlNS::style, "page-number").toInt());
529     }
530 
531     if (styleStack.hasProperty(KoXmlNS::style, "shadow")) {
532         KoShadowStyle shadow;
533         if (shadow.loadOdf(styleStack.property(KoXmlNS::style, "shadow")))
534             setShadow(shadow);
535     }
536 
537     // The fo:background-color attribute specifies the background color of a paragraph.
538     if (styleStack.hasProperty(KoXmlNS::fo, "background-color")) {
539         const QString bgcolor = styleStack.property(KoXmlNS::fo, "background-color");
540         QBrush brush = background();
541         if (bgcolor == "transparent")
542             brush.setStyle(Qt::NoBrush);
543         else {
544             if (brush.style() == Qt::NoBrush)
545                 brush.setStyle(Qt::SolidPattern);
546             brush.setColor(bgcolor); // #rrggbb format
547         }
548         setBackground(brush);
549     }
550 
551     // border-model
552     if (styleStack.hasProperty(KoXmlNS::table, "border-model")) {
553         QString val = styleStack.property(KoXmlNS::table, "border-model");
554         setCollapsingBorderModel(val == "collapsing");
555     }
556 }
557 
copyProperties(const KoTableStyle * style)558 void KoTableStyle::copyProperties(const KoTableStyle *style)
559 {
560     d->stylesPrivate = style->d->stylesPrivate;
561     setName(style->name()); // make sure we emit property change
562     d->next = style->d->next;
563     d->parentStyle = style->d->parentStyle;
564 }
565 
clone(QObject * parent)566 KoTableStyle *KoTableStyle::clone(QObject *parent)
567 {
568     KoTableStyle *newStyle = new KoTableStyle(parent);
569     newStyle->copyProperties(this);
570     return newStyle;
571 }
572 
573 
operator ==(const KoTableStyle & other) const574 bool KoTableStyle::operator==(const KoTableStyle &other) const
575 {
576     return other.d->stylesPrivate == d->stylesPrivate;
577 }
578 
removeDuplicates(const KoTableStyle & other)579 void KoTableStyle::removeDuplicates(const KoTableStyle &other)
580 {
581     d->stylesPrivate.removeDuplicates(other.d->stylesPrivate);
582 }
583 
isEmpty() const584 bool KoTableStyle::isEmpty() const
585 {
586     return d->stylesPrivate.isEmpty();
587 }
588 
saveOdf(KoGenStyle & style)589 void KoTableStyle::saveOdf(KoGenStyle &style)
590 {
591     QList<int> keys = d->stylesPrivate.keys();
592     if ((hasProperty(QTextFormat::FrameLeftMargin)) &&
593         (hasProperty(QTextFormat::FrameRightMargin)) &&
594         (hasProperty(QTextFormat::FrameTopMargin)) &&
595         (hasProperty(QTextFormat::FrameBottomMargin)) &&
596         (rightMargin() == leftMargin()) && (leftMargin() == topMargin()) && (topMargin() == bottomMargin()))
597     {
598         style.addPropertyLength("fo:margin", propertyLength(QTextFormat::FrameBottomMargin), KoGenStyle::TableType);
599         keys.removeAll(QTextFormat::FrameBottomMargin);
600         keys.removeAll(QTextFormat::FrameTopMargin);
601         keys.removeAll(QTextFormat::FrameRightMargin);
602         keys.removeAll(QTextFormat::FrameLeftMargin);
603     }
604     Q_FOREACH (int key, keys) {
605         if (key == QTextFormat::FrameWidth) {
606             QTextLength width = propertyLength(QTextFormat::FrameWidth);
607             if (width.type() == QTextLength::PercentageLength) {
608                 style.addPropertyLength("style:rel-width", width, KoGenStyle::TableType);
609             } else if (width.type() == QTextLength::FixedLength) {
610                 style.addPropertyLength("style:width", width, KoGenStyle::TableType);
611             }
612         } else if (key == QTextFormat::BlockAlignment) {
613             bool ok = false;
614             int alignValue = value(QTextFormat::BlockAlignment).toInt(&ok);
615             if (ok) {
616                 QString alignment = alignmentToString((Qt::Alignment) alignValue);
617                 if (!alignment.isEmpty())
618                     style.addProperty("table:align", alignment, KoGenStyle::TableType);
619             }
620         } else if (key == KoTableStyle::BreakBefore) {
621             style.addProperty("fo:break-before", KoText::textBreakToString(breakBefore()), KoGenStyle::TableType);
622         } else if (key == KoTableStyle::BreakAfter) {
623             style.addProperty("fo:break-after", KoText::textBreakToString(breakAfter()), KoGenStyle::TableType);
624         } else if (key == KoTableStyle::MayBreakBetweenRows) {
625             style.addProperty("style:may-break-between-rows", mayBreakBetweenRows(), KoGenStyle::TableType);
626         } else if (key == QTextFormat::BackgroundBrush) {
627             QBrush backBrush = background();
628             if (backBrush.style() != Qt::NoBrush)
629                 style.addProperty("fo:background-color", backBrush.color().name(), KoGenStyle::TableType);
630             else
631                 style.addProperty("fo:background-color", "transparent", KoGenStyle::TableType);
632         } else if (key == QTextFormat::FrameLeftMargin) {
633             style.addPropertyLength("fo:margin-left", propertyLength(QTextFormat::FrameLeftMargin), KoGenStyle::TableType);
634         } else if (key == QTextFormat::FrameRightMargin) {
635             style.addPropertyLength("fo:margin-right", propertyLength(QTextFormat::FrameRightMargin), KoGenStyle::TableType);
636         } else if (key == QTextFormat::FrameTopMargin) {
637             style.addPropertyLength("fo:margin-top", propertyLength(QTextFormat::FrameTopMargin), KoGenStyle::TableType);
638         } else if (key == QTextFormat::FrameBottomMargin) {
639             style.addPropertyLength("fo:margin-bottom", propertyLength(QTextFormat::FrameBottomMargin), KoGenStyle::TableType);
640         } else if (key == KoTableStyle::CollapsingBorders) {
641             if (collapsingBorderModel())
642                 style.addProperty("table:border-model", "collapsing", KoGenStyle::TableType);
643             else
644                 style.addProperty("table:border-model", "separating", KoGenStyle::TableType);
645         } else if (key == KoTableStyle::KeepWithNext) {
646             if (keepWithNext())
647                 style.addProperty("fo:keep-with-next", "always", KoGenStyle::TableType);
648             else
649                 style.addProperty("fo:keep-with-next", "auto", KoGenStyle::TableType);
650         } else if (key == KoTableStyle::Visible) {
651             style.addProperty("table:display", visible(), KoGenStyle::TableType);
652         } else if (key == KoTableStyle::PageNumber) {
653             if (pageNumber() > 0)
654                 style.addProperty("style:page-number", pageNumber(), KoGenStyle::TableType);
655             else
656                 style.addProperty("style:page-number", "auto", KoGenStyle::TableType);
657         } else if (key == TextProgressionDirection) {
658             style.addProperty("style:writing-mode", KoText::directionToString(textDirection()), KoGenStyle::TableType);
659         } else if (key == KoTableStyle::Shadow) {
660             style.addProperty("style:shadow", shadow().saveOdf());
661         }
662     }
663 }
664