1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2009 Inge Wallin <inge@lysator.liu.se>
4  * Copyright (C) 2009 Thomas Zander <zander@kde.org>
5  * Copyright (C) 2011 Pierre Ducroquet <pinaraf@pinaraf.info>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "KoBorder.h"
24 
25 #include <QPainter>
26 
27 #include <OdfDebug.h>
28 
29 #include <KoUnit.h>
30 #include <KoXmlNS.h>
31 #include <KoXmlReader.h>
32 #include <KoStyleStack.h>
33 
34 
35 class KoBorderPrivate : public QSharedData
36 {
37 public:
38     KoBorderPrivate();
39     ~KoBorderPrivate();
40 
41     QMap<KoBorder::BorderSide, KoBorder::BorderData> data;
42 };
43 
KoBorderPrivate()44 KoBorderPrivate::KoBorderPrivate()
45 {
46 }
47 
~KoBorderPrivate()48 KoBorderPrivate::~KoBorderPrivate()
49 {
50 }
51 
BorderData()52 KoBorder::BorderData::BorderData()
53     : style(KoBorder::BorderNone)
54     , outerPen(QPen())
55     , innerPen(QPen())
56     , spacing(0)
57 {
58     outerPen.setWidthF(0.0f);
59     innerPen.setWidthF(0.0f);
60 }
61 
operator ==(const KoBorder::BorderData & other) const62 bool KoBorder::BorderData::operator==(const KoBorder::BorderData& other) const
63 {
64     // Left Borders
65     if (style == BorderNone && other.style == BorderNone) {
66         // If both styles are None, then the rest of the values don't
67         // need to be compared.
68         ;
69     }
70     else if (style != other.style) {
71         // If any of them are non-None, and they are different, the
72         // borders are also different.
73         return false;
74     }
75     else {
76         // Here we know that the border styles are the same, now
77         // compare the rest of the values.
78         if (outerPen != other.outerPen)
79             return false;
80 
81         // If the border style == BorderDouble, then compare a couple
82         // of other values too.
83         if (style == BorderDouble) {
84             if (innerPen != other.innerPen)
85                 return false;
86             if (spacing != other.spacing)
87                 return false;
88         }
89     }
90 
91     return true;
92 }
93 
94 // ----------------------------------------------------------------
95 
KoBorder()96 KoBorder::KoBorder()
97     : d(new KoBorderPrivate)
98 {
99 }
100 
KoBorder(const KoBorder & kb)101 KoBorder::KoBorder(const KoBorder &kb)
102     : d(kb.d)
103 {
104 }
105 
~KoBorder()106 KoBorder::~KoBorder()
107 {
108     // No delete because d is a QSharedDataPointer.
109 }
110 
111 
112 // ----------------------------------------------------------------
113 //                             operators
114 
operator =(const KoBorder & other)115 KoBorder &KoBorder::operator=(const KoBorder &other)
116 {
117     d = other.d;
118 
119     return *this;
120 }
121 
operator ==(const KoBorder & other) const122 bool KoBorder::operator==(const KoBorder &other) const
123 {
124     if (d.data() == other.d.data())
125         return true;
126 
127 
128     if (d->data.size() != other.d->data.size())
129         return false;
130 
131     KoBorder::BorderSide key;
132 
133     foreach (key, d->data.keys()) {
134         if (!other.d->data.contains(key))
135             return false;
136         if (!(other.d->data[key] == d->data[key]))
137             return false;
138     }
139 
140     return true;
141 }
142 
143 
144 // ----------------------------------------------------------------
145 //                 public, non-class functions
146 
odfBorderStyle(const QString & borderstyle,bool * converted)147 KoBorder::BorderStyle KoBorder::odfBorderStyle(const QString &borderstyle, bool *converted)
148 {
149     // Note: the styles marked "Not odf compatible" below are legacies
150     //       from the old words format.  There are also lots of border
151     //       styles in the MS DOC that we may have to handle at some point.
152     if (converted)
153         *converted = true;
154     if (borderstyle == "none")
155         return BorderNone;
156     if (borderstyle == "solid")
157         return BorderSolid;
158     if (borderstyle == "dashed")
159         return BorderDashed;
160     if (borderstyle == "dotted")
161         return BorderDotted;
162     if (borderstyle == "dot-dash")
163         return BorderDashDot;
164     if (borderstyle == "dot-dot-dash")
165         return BorderDashDotDot;
166     if (borderstyle == "double")
167         return BorderDouble;
168     if (borderstyle == "groove")   // Not odf compatible -- see above
169         return BorderGroove;
170     if (borderstyle == "ridge")   // Not odf compatible -- see above
171         return BorderRidge;
172     if (borderstyle == "inset")   // Not odf compatible -- see above
173         return BorderInset;
174     if (borderstyle == "outset")   // Not odf compatible -- see above
175         return BorderOutset;
176     if (borderstyle == "dash-largegap")
177         return KoBorder::BorderDashedLong;
178     if (borderstyle == "slash") // not officially odf, but we support it anyway
179         return KoBorder::BorderSlash;
180     if (borderstyle == "wave") // not officially odf, but we support it anyway
181         return KoBorder::BorderWave;
182     if (borderstyle == "double-wave") // not officially odf, but we support it anyway
183         return KoBorder::BorderDoubleWave;
184 
185     if (converted)
186         *converted = false;
187 
188     return BorderSolid;
189 }
190 
odfBorderStyleString(BorderStyle borderstyle)191 QString KoBorder::odfBorderStyleString(BorderStyle borderstyle)
192 {
193     switch (borderstyle) {
194     case BorderDashed:
195         return QString("dashed");
196     case BorderDotted:
197         return QString("dotted");
198     case BorderDashDot:
199         return QString("dot-dash");
200     case BorderDashDotDot:
201         return QString("dot-dot-dash");
202     case BorderDouble:
203         return QString("double");
204     case BorderGroove:
205         return QString("groove"); // not odf -- see above
206     case BorderRidge:
207         return QString("ridge"); // not odf -- see above
208     case BorderInset:
209         return QString("inset"); // not odf -- see above
210     case BorderOutset:
211         return QString("outset"); // not odf -- see above
212     case BorderSolid:
213         return QString("solid");
214     case BorderNone:
215         return QString("none");
216 
217     default:
218         // Handle unknown types as solid.
219         return QString("solid");
220     }
221 }
222 
msoBorderStyleString(BorderStyle borderstyle)223 QString KoBorder::msoBorderStyleString(BorderStyle borderstyle)
224 {
225     switch (borderstyle) {
226     case KoBorder::BorderDashedLong:
227         return QString("dash-largegap");
228     case KoBorder::BorderSlash:
229         return QString("slash"); // not officially odf, but we support it anyway
230     case KoBorder::BorderWave:
231         return QString("wave"); // not officially odf, but we support it anyway
232     case KoBorder::BorderDoubleWave:
233         return QString("double-wave"); // not officially odf, but we support it anyway
234 
235     default:
236         // Handle remaining styles as odf type style.
237         return odfBorderStyleString(borderstyle);
238     }
239 }
240 
241 
242 // ----------------------------------------------------------------
243 //                         Getters and Setters
244 
245 
setBorderStyle(BorderSide side,BorderStyle style)246 void KoBorder::setBorderStyle(BorderSide side, BorderStyle style)
247 {
248     if (d->data[side].style == style) {
249         return;
250     }
251 
252     if (!d->data.contains(side)) {
253         BorderData data;
254         data.style = style;
255         d->data[side] = data;
256     } else {
257         d->data[side].style = style;
258     }
259 
260     // Make a best effort to create the best possible dash pattern for the chosen style.
261     // FIXME: KoTableCellStyle::setEdge() should call this function.
262     BorderData &edge = d->data[side];
263     qreal width = edge.outerPen.widthF();
264     qreal innerWidth = 0;
265     qreal middleWidth = 0;
266     qreal space = 0;
267     QVector<qreal> dashes;
268     switch (style) {
269     case KoBorder::BorderNone:
270         width = 0.0;
271         break;
272     case KoBorder::BorderDouble:
273         innerWidth = space = edge.outerPen.width() / 3; //some nice default look
274         width -= (space + innerWidth);
275         edge.outerPen.setStyle(Qt::SolidLine);
276         break;
277     case KoBorder::BorderDotted:
278         dashes << 1 << 1;
279         edge.outerPen.setDashPattern(dashes);
280         break;
281     case KoBorder::BorderDashed:
282         dashes << 4 << 1;
283         edge.outerPen.setDashPattern(dashes);
284         break;
285     case KoBorder::BorderDashedLong: {
286         dashes << 4 << 4;
287         edge.outerPen.setDashPattern(dashes);
288         break;
289     }
290     case KoBorder::BorderTriple:
291         innerWidth = middleWidth = space = width/6;
292         width -= (space + innerWidth);
293         edge.outerPen.setStyle(Qt::SolidLine);
294         break;
295     case KoBorder::BorderDashDot:
296         dashes << 3 << 3<< 7 << 3;
297         edge.outerPen.setDashPattern(dashes);
298         break;
299     case KoBorder::BorderDashDotDot:
300         dashes << 2 << 2<< 6 << 2 << 2 << 2;
301         edge.outerPen.setDashPattern(dashes);
302         break;
303     case KoBorder::BorderWave:
304         edge.outerPen.setStyle(Qt::SolidLine);
305         break;
306     case KoBorder::BorderSlash:
307         edge.outerPen.setStyle(Qt::SolidLine);
308         break;
309     case KoBorder::BorderDoubleWave:
310         innerWidth = space = width/3; //some nice default look
311         width -= (space + innerWidth);
312         edge.outerPen.setStyle(Qt::SolidLine);
313         break;
314     default:
315         edge.outerPen.setStyle(Qt::SolidLine);
316         break;
317     }
318     edge.outerPen.setJoinStyle(Qt::MiterJoin);
319     edge.outerPen.setCapStyle(Qt::FlatCap);
320     edge.outerPen.setWidthF(width);
321 
322     edge.spacing = space;
323     edge.innerPen = edge.outerPen;
324     edge.innerPen.setWidthF(innerWidth);
325 }
326 
borderStyle(BorderSide side) const327 KoBorder::BorderStyle KoBorder::borderStyle(BorderSide side) const
328 {
329     if (!d->data.contains(side)) {
330         return BorderNone;
331     } else {
332         return d->data[side].style;
333     }
334 }
335 
setBorderColor(BorderSide side,const QColor & color)336 void KoBorder::setBorderColor(BorderSide side, const QColor &color)
337 {
338     if (!d->data.contains(side)) {
339         BorderData data;
340         data.outerPen.setColor(color);
341         d->data[side] = data;
342     } else {
343         d->data[side].outerPen.setColor(color);
344     }
345 }
346 
borderColor(BorderSide side) const347 QColor KoBorder::borderColor(BorderSide side) const
348 {
349     if (!d->data.contains(side)) {
350         return QColor();
351     } else {
352         return d->data[side].outerPen.color();
353     }
354 }
355 
setBorderWidth(BorderSide side,qreal width)356 void KoBorder::setBorderWidth(BorderSide side, qreal width)
357 {
358     if (!d->data.contains(side)) {
359         BorderData data;
360         data.outerPen.setWidthF(width);
361         d->data[side] = data;
362     } else {
363         d->data[side].outerPen.setWidthF(width);
364     }
365 }
366 
borderWidth(BorderSide side) const367 qreal KoBorder::borderWidth(BorderSide side) const
368 {
369     if (!d->data.contains(side)) {
370         return 0;
371     } else {
372         if (d->data[side].style == BorderDouble)
373             return (d->data[side].outerPen.widthF() + d->data[side].innerPen.widthF()
374                     + d->data[side].spacing);
375         else
376             return d->data[side].outerPen.widthF();
377     }
378 }
379 
setOuterBorderWidth(BorderSide side,qreal width)380 void KoBorder::setOuterBorderWidth(BorderSide side, qreal width)
381 {
382     if (!d->data.contains(side)) {
383         BorderData data;
384         data.outerPen.setWidthF(width);
385         d->data[side] = data;
386     } else {
387         d->data[side].outerPen.setWidthF(width);
388     }
389 }
390 
outerBorderWidth(BorderSide side) const391 qreal KoBorder::outerBorderWidth(BorderSide side) const
392 {
393     if (!d->data.contains(side)) {
394         return 0;
395     } else {
396         return d->data[side].outerPen.widthF();
397     }
398 }
399 
setInnerBorderWidth(BorderSide side,qreal width)400 void KoBorder::setInnerBorderWidth(BorderSide side, qreal width)
401 {
402     if (!d->data.contains(side)) {
403         BorderData data;
404         data.innerPen.setWidthF(width);
405         d->data[side] = data;
406     } else {
407         d->data[side].innerPen.setWidthF(width);
408     }
409 }
410 
innerBorderWidth(BorderSide side) const411 qreal KoBorder::innerBorderWidth(BorderSide side) const
412 {
413     if (!d->data.contains(side)) {
414         return 0;
415     } else {
416         return d->data[side].innerPen.widthF();
417     }
418 }
419 
setBorderSpacing(BorderSide side,qreal width)420 void KoBorder::setBorderSpacing(BorderSide side, qreal width)
421 {
422     if (!d->data.contains(side)) {
423         BorderData data;
424         data.spacing = width;
425         d->data[side] = data;
426     } else {
427         d->data[side].spacing = width;
428     }
429 }
430 
borderSpacing(BorderSide side) const431 qreal KoBorder::borderSpacing(BorderSide side) const
432 {
433     if (!d->data.contains(side)) {
434         return 0;
435     } else {
436         return d->data[side].spacing;
437     }
438 }
439 
440 
borderData(BorderSide side) const441 KoBorder::BorderData KoBorder::borderData(BorderSide side) const
442 {
443     return d->data.value(side, BorderData());
444 }
445 
setBorderData(BorderSide side,const BorderData & data)446 void KoBorder::setBorderData(BorderSide side, const BorderData &data)
447 {
448     d->data[side] = data;
449 }
450 
451 
452 // -------------------------------
453 
hasBorder() const454 bool KoBorder::hasBorder() const
455 {
456     if (borderStyle(LeftBorder) != BorderNone && borderWidth(LeftBorder) > 0.0)
457         return true;
458     if (borderStyle(RightBorder) != BorderNone && borderWidth(RightBorder) > 0.0)
459         return true;
460     if (borderStyle(TopBorder) != BorderNone && borderWidth(TopBorder) > 0.0)
461         return true;
462     if (borderStyle(BottomBorder) != BorderNone && borderWidth(BottomBorder) > 0.0)
463         return true;
464     if (borderStyle(TlbrBorder) != BorderNone && borderWidth(TlbrBorder) > 0.0)
465         return true;
466     if (borderStyle(BltrBorder) != BorderNone && borderWidth(BltrBorder) > 0.0)
467         return true;
468     return false;
469 }
470 
hasBorder(KoBorder::BorderSide side) const471 bool KoBorder::hasBorder(KoBorder::BorderSide side) const
472 {
473     return borderStyle(side) != BorderNone && borderWidth(side) > 0.0;
474 }
475 
476 
477 // ----------------------------------------------------------------
478 //                         painting
479 
480 
paint(QPainter & painter,const QRectF & borderRect,BorderPaintArea whereToPaint) const481 void KoBorder::paint(QPainter &painter, const QRectF &borderRect,
482                      BorderPaintArea whereToPaint) const
483 {
484     Q_UNUSED(whereToPaint);
485     // In tables it is apparently best practice to paint the
486     // horizontal lines over the vertical ones.  So let's use the same
487     // strategy here.
488 
489     QPointF start;
490     QPointF end;
491 
492     // FIXME: Make KoBorder store pointers to BorderData instead.  This is very inefficient.
493     BorderData leftEdge = borderData(KoBorder::LeftBorder);
494     BorderData rightEdge = borderData(KoBorder::RightBorder);
495     BorderData topEdge = borderData(KoBorder::TopBorder);
496     BorderData bottomEdge = borderData(KoBorder::BottomBorder);
497 
498     // Left border
499     if (hasBorder(LeftBorder)) {
500         start = borderRect.topLeft();
501         end   = borderRect.bottomLeft();
502         paintBorderSide(painter, start, end, &leftEdge, true,
503                         hasBorder(TopBorder) ? &topEdge : 0,
504                         hasBorder(BottomBorder) ? &bottomEdge : 0,
505                         1);
506     }
507 
508     // Right border
509     if (hasBorder(RightBorder)) {
510         start = borderRect.topRight();
511         end   = borderRect.bottomRight();
512         paintBorderSide(painter, start, end, &rightEdge, true,
513                         hasBorder(TopBorder) ? &topEdge : 0,
514                         hasBorder(BottomBorder) ? &bottomEdge : 0,
515                         -1);
516     }
517 
518     // Top border
519     if (hasBorder(TopBorder)) {
520         start = borderRect.topLeft();
521         end   = borderRect.topRight();
522         paintBorderSide(painter, start, end, &topEdge, false,
523                         hasBorder(LeftBorder) ? &leftEdge : 0,
524                         hasBorder(RightBorder) ? &rightEdge : 0,
525                         1);
526     }
527 
528     // Bottom border
529     if (hasBorder(BottomBorder)) {
530         start = borderRect.bottomLeft();
531         end   = borderRect.bottomRight();
532         paintBorderSide(painter, start, end, &bottomEdge, false,
533                         hasBorder(LeftBorder) ? &leftEdge : 0,
534                         hasBorder(RightBorder) ? &rightEdge : 0,
535                         -1);
536     }
537 
538     // FIXME: Diagonal borders
539 }
540 
paintBorderSide(QPainter & painter,QPointF lineStart,QPointF lineEnd,BorderData * borderData,bool isVertical,BorderData * neighbour1,BorderData * neighbour2,int inwardsAcross) const541 void KoBorder::paintBorderSide(QPainter &painter, QPointF lineStart, QPointF lineEnd,
542                                BorderData *borderData, bool isVertical,
543                                BorderData *neighbour1, BorderData *neighbour2,
544                                int inwardsAcross) const
545 {
546     // Adjust the outer line so that it is inside the boundary.
547     qreal displacement = borderData->outerPen.widthF() / qreal(2.0);
548     if (isVertical) {
549         lineStart.setX(lineStart.x() + inwardsAcross * displacement);
550         lineEnd.setX(lineEnd.x() + inwardsAcross * displacement);
551     }
552     else {
553         lineStart.setY(lineStart.y() + inwardsAcross * displacement);
554         lineEnd.setY(lineEnd.y() + inwardsAcross * displacement);
555     }
556 
557     painter.setPen(borderData->outerPen);
558     painter.drawLine(lineStart, lineEnd);
559 
560     if (borderData->style == BorderDouble) {
561         displacement = (borderData->outerPen.widthF() / qreal(2.0)
562                         + borderData->spacing
563                         + borderData->innerPen.widthF() / qreal(2.0));
564         if (isVertical) {
565             lineStart.setX(lineStart.x() + inwardsAcross * displacement);
566             lineEnd.setX(lineEnd.x() + inwardsAcross * displacement);
567         }
568         else {
569             lineStart.setY(lineStart.y() + inwardsAcross * displacement);
570             lineEnd.setY(lineEnd.y() + inwardsAcross * displacement);
571         }
572 
573         // Adjust for neighboring inner lines.
574         if (neighbour1 && neighbour1->style == BorderDouble) {
575             displacement = neighbour1->outerPen.widthF() + neighbour1->spacing;
576             if (isVertical) {
577                 lineStart.setY(lineStart.y() + displacement);
578             }
579             else {
580                 lineStart.setX(lineStart.x() + displacement);
581             }
582         }
583         if (neighbour2 && neighbour2->style == BorderDouble) {
584             displacement = neighbour2->outerPen.widthF() + neighbour2->spacing;
585             if (isVertical) {
586                 lineEnd.setY(lineEnd.y() - displacement);
587             }
588             else {
589                 lineEnd.setX(lineEnd.x() - displacement);
590             }
591         }
592 
593         // Draw the inner line.
594         painter.setPen(borderData->innerPen);
595         painter.drawLine(lineStart, lineEnd);
596     }
597 }
598 
599 
600 // ----------------------------------------------------------------
601 //                         static functions
602 
603 
parseOdfBorder(const QString & border,QColor * color,KoBorder::BorderStyle * borderStyle,bool * hasBorderStyle,qreal * borderWidth,bool * hasBorderWidth)604 void parseOdfBorder(const QString &border, QColor *color,
605                     KoBorder::BorderStyle *borderStyle, bool *hasBorderStyle,
606                     qreal *borderWidth, bool *hasBorderWidth)
607 {
608     *hasBorderStyle = false;
609     *hasBorderWidth = false;
610 
611     if (!border.isEmpty() && border != "none" && border != "hidden") {
612         QStringList borderData = border.split(' ', QString::SkipEmptyParts);
613         if (borderData.length() > 0)
614         {
615             const QColor borderColor = QColor(borderData.last());
616             if (borderColor.isValid()) {
617                 *color = borderColor;
618                 borderData.removeLast();
619             }
620 
621             bool converted = false;
622             const KoBorder::BorderStyle parsedBorderStyle = KoBorder::odfBorderStyle(borderData.last(), &converted);
623             if (converted) {
624                 *hasBorderStyle = true;
625                 borderData.removeLast();
626                 *borderStyle = parsedBorderStyle;
627             }
628 
629             if (!borderData.isEmpty()) {
630                 const qreal parsedBorderWidth = KoUnit::parseValue(borderData[0], 1.0);
631                 *borderWidth = parsedBorderWidth;
632                 *hasBorderWidth = true;
633             }
634         }
635     }
636 }
637 
638 // ----------------------------------------------------------------
639 //                         load and save
640 
loadOdf(const KoXmlElement & style)641 bool KoBorder::loadOdf(const KoXmlElement &style)
642 {
643     bool result = false;
644 
645     QString borderString;
646     bool hasSpecialBorder;
647     QString specialBorderString;
648     if (style.hasAttributeNS(KoXmlNS::fo, "border")) {
649         borderString = style.attributeNS(KoXmlNS::fo, "border");
650         if (borderString == "none") {
651             // We use the "false" to indicate that there is no border
652             // rather than that the parsing has failed.
653             return false;
654         }
655 
656         result = true;
657         if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder"))) {
658             specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder");
659         }
660         parseAndSetBorder(borderString, hasSpecialBorder, specialBorderString);
661     }
662     else {
663         // No common border attributes, check for the individual ones.
664         if (style.hasAttributeNS(KoXmlNS::fo, "border-left")) {
665             result = true;
666             borderString = style.attributeNS(KoXmlNS::fo, "border-left");
667             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-left"))) {
668                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-left");
669             }
670             parseAndSetBorder(LeftBorder, borderString, hasSpecialBorder, specialBorderString);
671         }
672         if (style.hasAttributeNS(KoXmlNS::fo, "border-top")) {
673             result = true;
674             borderString = style.attributeNS(KoXmlNS::fo, "border-top");
675             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-top"))) {
676                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-top");
677             }
678             parseAndSetBorder(TopBorder, borderString, hasSpecialBorder, specialBorderString);
679         }
680         if (style.hasAttributeNS(KoXmlNS::fo, "border-right")) {
681             result = true;
682             borderString = style.attributeNS(KoXmlNS::fo, "border-right");
683             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-right"))) {
684                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-right");
685             }
686             parseAndSetBorder(RightBorder, borderString, hasSpecialBorder, specialBorderString);
687         }
688         if (style.hasAttributeNS(KoXmlNS::fo, "border-bottom")) {
689             result = true;
690             borderString = style.attributeNS(KoXmlNS::fo, "border-bottom");
691             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-bottom"))) {
692                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-bottom");
693             }
694             parseAndSetBorder(BottomBorder, borderString, hasSpecialBorder, specialBorderString);
695         }
696     }
697 
698     // Diagonals are treated individually and are NOT part of <style:border>.
699     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-tl-br")) {
700         result = true;
701         borderString = style.attributeNS(KoXmlNS::fo, "border-tl-br");
702         if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-tl-br"))) {
703             specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-tl-br");
704         }
705         parseAndSetBorder(TlbrBorder, borderString, hasSpecialBorder, specialBorderString);
706     }
707     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-bl-tr")) {
708         result = true;
709         borderString = style.attributeNS(KoXmlNS::fo, "border-bl-tr");
710         if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-bl-tr"))) {
711             specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-bl-tr");
712         }
713         parseAndSetBorder(BltrBorder, borderString, hasSpecialBorder, specialBorderString);
714     }
715 
716     // Handle double borders.
717     if (style.hasAttributeNS(KoXmlNS::style, "border-line-width")) {
718         result = true;
719         QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width");
720         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
721             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
722             setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
723             setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
724             setBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
725 
726             setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
727             setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
728             setBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
729 
730             setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
731             setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
732             setBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
733 
734             setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
735             setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
736             setBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
737         }
738     }
739     else {
740         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-left")) {
741             result = true;
742             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-left");
743             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
744                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
745                 setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
746                 setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
747                 setBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
748             }
749         }
750         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-top")) {
751             result = true;
752             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-top");
753             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
754                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
755                 setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
756                 setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
757                 setBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
758             }
759         }
760         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-right")) {
761             result = true;
762             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-right");
763             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
764                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
765                 setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
766                 setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
767                 setBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
768             }
769         }
770         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-bottom")) {
771             result = true;
772             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-bottom");
773             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
774                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
775                 setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
776                 setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
777                 setBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
778             }
779         }
780     }
781 
782     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-tl-br-widths")) {
783         result = true;
784         QString borderLineWidth = style.attributeNS(KoXmlNS::style, "diagonal-tl-br-widths");
785         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
786             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
787             setInnerBorderWidth(TlbrBorder, KoUnit::parseValue(blw[0], 0.1));
788             setBorderSpacing(TlbrBorder, KoUnit::parseValue(blw[1], 1.0));
789             setBorderWidth(TlbrBorder, KoUnit::parseValue(blw[2], 0.1));
790         }
791     }
792     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-bl-tr-widths")) {
793         result = true;
794         QString borderLineWidth = style.attributeNS(KoXmlNS::style, "diagonal-bl-tr-widths");
795         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
796             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
797             setInnerBorderWidth(BltrBorder, KoUnit::parseValue(blw[0], 0.1));
798             setBorderSpacing(BltrBorder, KoUnit::parseValue(blw[1], 1.0));
799             setBorderWidth(BltrBorder, KoUnit::parseValue(blw[2], 0.1));
800         }
801     }
802     return result;
803 }
804 
loadOdf(const KoStyleStack & styleStack)805 bool KoBorder::loadOdf(const KoStyleStack &styleStack)
806 {
807     bool result = false;
808 
809     QString borderString;
810     bool hasSpecialBorder;
811     QString specialBorderString;
812     if (styleStack.hasProperty(KoXmlNS::fo, "border")) {
813         result = true;
814         borderString = styleStack.property(KoXmlNS::fo, "border");
815         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder"))) {
816             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder");
817         }
818         parseAndSetBorder(borderString, hasSpecialBorder, specialBorderString);
819     }
820 
821     // Even if there are common border attributes, check for the
822     // individual ones since they have precedence.
823 
824     if (styleStack.hasProperty(KoXmlNS::fo, "border-left")) {
825         result = true;
826         borderString = styleStack.property(KoXmlNS::fo, "border-left");
827         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-left"))) {
828             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-left");
829         }
830         parseAndSetBorder(LeftBorder, borderString, hasSpecialBorder, specialBorderString);
831     }
832     if (styleStack.hasProperty(KoXmlNS::fo, "border-top")) {
833         result = true;
834         borderString = styleStack.property(KoXmlNS::fo, "border-top");
835         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-top"))) {
836             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-top");
837         }
838         parseAndSetBorder(TopBorder, borderString, hasSpecialBorder, specialBorderString);
839     }
840     if (styleStack.hasProperty(KoXmlNS::fo, "border-right")) {
841         result = true;
842         borderString = styleStack.property(KoXmlNS::fo, "border-right");
843         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-right"))) {
844             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-right");
845         }
846         parseAndSetBorder(RightBorder, borderString, hasSpecialBorder, specialBorderString);
847 
848     }
849     if (styleStack.hasProperty(KoXmlNS::fo, "border-bottom")) {
850         result = true;
851         borderString = styleStack.property(KoXmlNS::fo, "border-bottom");
852         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-bottom"))) {
853             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-bottom");
854         }
855         parseAndSetBorder(BottomBorder, borderString, hasSpecialBorder, specialBorderString);
856     }
857 
858     // Diagonals are treated individually and are NOT part of <style:border>.
859     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-tl-br")) {
860         result = true;
861         borderString = styleStack.property(KoXmlNS::fo, "border-tl-br");
862         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-tl-br"))) {
863             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-tl-br");
864         }
865         parseAndSetBorder(TlbrBorder, borderString, hasSpecialBorder, specialBorderString);
866     }
867     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-bl-tr")) {
868         result = true;
869         borderString = styleStack.property(KoXmlNS::fo, "border-bl-tr");
870         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-bl-tr"))) {
871             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-bl-tr");
872         }
873         parseAndSetBorder(BltrBorder, borderString, hasSpecialBorder, specialBorderString);
874     }
875 
876     // Handle double borders.
877     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width")) {
878         result = true;
879         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width");
880         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
881             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
882             setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
883             setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
884             setBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
885 
886             setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
887             setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
888             setBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
889 
890             setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
891             setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
892             setBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
893 
894             setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
895             setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
896             setBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
897         }
898     }
899     // Even if there are common border attributes, check for the
900     // individual ones since they have precedence.
901 
902     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-left")) {
903         result = true;
904         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-left");
905         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
906             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
907             setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
908             setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
909             setBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
910         }
911     }
912     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-top")) {
913         result = true;
914         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-top");
915         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
916             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
917             setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
918             setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
919             setBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
920         }
921     }
922     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-right")) {
923         result = true;
924         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-right");
925         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
926             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
927             setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
928             setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
929             setBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
930         }
931     }
932     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-bottom")) {
933         result = true;
934         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-bottom");
935         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
936             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
937             setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
938             setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
939             setBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
940         }
941     }
942 
943     // Diagonals are treated individually and are NOT part of <style:border>.
944     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-tl-br-widths")) {
945         result = true;
946         QString borderLineWidth = styleStack.property(KoXmlNS::style, "diagonal-tl-br-widths");
947         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
948             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
949             setInnerBorderWidth(TlbrBorder, KoUnit::parseValue(blw[0], 0.1));
950             setBorderSpacing(TlbrBorder, KoUnit::parseValue(blw[1], 1.0));
951             setBorderWidth(TlbrBorder, KoUnit::parseValue(blw[2], 0.1));
952         }
953     }
954     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-bl-tr-widths")) {
955         result = true;
956         QString borderLineWidth = styleStack.property(KoXmlNS::style, "diagonal-bl-tr-widths");
957         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
958             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
959             setInnerBorderWidth(BltrBorder, KoUnit::parseValue(blw[0], 0.1));
960             setBorderSpacing(BltrBorder, KoUnit::parseValue(blw[1], 1.0));
961             setBorderWidth(BltrBorder, KoUnit::parseValue(blw[2], 0.1));
962         }
963     }
964 
965     return result;
966 }
967 
968 
969 // Private
parseAndSetBorder(const QString & borderString,bool hasSpecialBorder,const QString & specialBorderString)970 void KoBorder::parseAndSetBorder(const QString &borderString,
971                                  bool hasSpecialBorder, const QString &specialBorderString)
972 {
973     if (borderString == "none") {
974         return;
975     }
976 
977     //debugOdf << "*** *** Found border: " << border;
978     QColor bordersColor;
979     BorderStyle bordersStyle;
980     qreal bordersWidth;
981     bool foundStyle;
982     bool foundWidth;
983     parseOdfBorder(borderString, &bordersColor, &bordersStyle, &foundStyle,
984                    &bordersWidth, &foundWidth);
985     if (bordersColor.isValid()) {
986         setBorderColor(LeftBorder, bordersColor);
987         setBorderColor(TopBorder, bordersColor);
988         setBorderColor(RightBorder, bordersColor);
989         setBorderColor(BottomBorder, bordersColor);
990     }
991     if (hasSpecialBorder) {
992         bordersStyle = KoBorder::odfBorderStyle(specialBorderString, &foundStyle);
993     }
994 
995     if (foundStyle) {
996         setBorderStyle(LeftBorder, bordersStyle);
997         setBorderStyle(TopBorder, bordersStyle);
998         setBorderStyle(RightBorder, bordersStyle);
999         setBorderStyle(BottomBorder, bordersStyle);
1000     }
1001     if (foundWidth) {
1002         setBorderWidth(LeftBorder, bordersWidth);
1003         setBorderWidth(TopBorder, bordersWidth);
1004         setBorderWidth(RightBorder, bordersWidth);
1005         setBorderWidth(BottomBorder, bordersWidth);
1006     }
1007 }
1008 
1009 // Private
parseAndSetBorder(const BorderSide borderSide,const QString & borderString,bool hasSpecialBorder,const QString & specialBorderString)1010 void KoBorder::parseAndSetBorder(const BorderSide borderSide, const QString &borderString,
1011                                  bool hasSpecialBorder, const QString &specialBorderString)
1012 {
1013     QColor borderColor;
1014     BorderStyle borderStyle;
1015     qreal borderWidth;
1016     bool foundStyle;
1017     bool foundWidth;
1018 
1019     parseOdfBorder(borderString, &borderColor, &borderStyle, &foundStyle,
1020                    &borderWidth, &foundWidth);
1021     if (borderColor.isValid()) {
1022         setBorderColor(borderSide, borderColor);
1023     }
1024     if (hasSpecialBorder) {
1025         borderStyle = KoBorder::odfBorderStyle(specialBorderString, &foundStyle);
1026     }
1027 
1028     if (foundStyle) {
1029         setBorderStyle( borderSide, borderStyle);
1030     }
1031     if (foundWidth) {
1032         setBorderWidth( borderSide, borderWidth);
1033     }
1034 }
1035 
saveOdf(KoGenStyle & style,KoGenStyle::PropertyType type) const1036 void KoBorder::saveOdf(KoGenStyle &style, KoGenStyle::PropertyType type) const
1037 {
1038     // Get the strings that describe respective borders.
1039     QString leftBorderString = QString("%1pt %2 %3")
1040                                  .arg(QString::number(borderWidth(LeftBorder)),
1041                                       odfBorderStyleString(borderStyle(LeftBorder)),
1042                                       borderColor(LeftBorder).name());
1043     QString rightBorderString =  QString("%1pt %2 %3")
1044                                   .arg(QString::number(borderWidth(RightBorder)),
1045                                        odfBorderStyleString(borderStyle(RightBorder)),
1046                                        borderColor(RightBorder).name());
1047     QString topBorderString = QString("%1pt %2 %3")
1048                                 .arg(QString::number(borderWidth(TopBorder)),
1049                                      odfBorderStyleString(borderStyle(TopBorder)),
1050                                      borderColor(TopBorder).name());
1051     QString bottomBorderString = QString("%1pt %2 %3")
1052                                    .arg(QString::number(borderWidth(BottomBorder)),
1053                                         odfBorderStyleString(borderStyle(BottomBorder)),
1054                                         borderColor(BottomBorder).name());
1055 
1056     QString tlbrBorderString = QString("%1pt %2 %3")
1057                                 .arg(QString::number(borderWidth(TlbrBorder)),
1058                                      odfBorderStyleString(borderStyle(TlbrBorder)),
1059                                      borderColor(TlbrBorder).name());
1060     QString trblBorderString = QString("%1pt %2 %3")
1061                                    .arg(QString::number(borderWidth(BltrBorder)),
1062                                         odfBorderStyleString(borderStyle(BltrBorder)),
1063                                         borderColor(BltrBorder).name());
1064 
1065     // Get the strings that describe respective special borders (for special mso support).
1066     QString leftBorderSpecialString = msoBorderStyleString(borderStyle(LeftBorder));
1067     QString rightBorderSpecialString = msoBorderStyleString(borderStyle(RightBorder));
1068     QString topBorderSpecialString = msoBorderStyleString(borderStyle(TopBorder));
1069     QString bottomBorderSpecialString = msoBorderStyleString(borderStyle(BottomBorder));
1070     QString tlbrBorderSpecialString = msoBorderStyleString(borderStyle(TlbrBorder));
1071     QString trblBorderSpecialString = msoBorderStyleString(borderStyle(BltrBorder));
1072 
1073     // Check if we can save all borders in one fo:border attribute, or
1074     // if we have to use several different ones like fo:border-left, etc.
1075     if (leftBorderString == rightBorderString
1076         && leftBorderString == topBorderString
1077         && leftBorderString == bottomBorderString) {
1078 
1079         // Yes, they were all the same, so use only fo:border
1080         style.addProperty("fo:border", leftBorderString, type);
1081         style.addProperty("calligra:specialborder-left", leftBorderSpecialString, type);
1082         style.addProperty("calligra:specialborder-right", rightBorderSpecialString, type);
1083         style.addProperty("calligra:specialborder-top", topBorderSpecialString, type);
1084         style.addProperty("calligra:specialborder-bottom", bottomBorderSpecialString, type);
1085     } else {
1086         // No, they were different, so use the individual borders.
1087         //if (leftBorderStyle() != BorderNone)
1088             style.addProperty("fo:border-left", leftBorderString, type);
1089             style.addProperty("calligra:specialborder-left", leftBorderSpecialString, type);
1090         //if (rightBorderStyle() != BorderNone)
1091             style.addProperty("fo:border-right", rightBorderString, type);
1092             style.addProperty("calligra:specialborder-right", rightBorderSpecialString, type);
1093         //if (topBorderStyle() != BorderNone)
1094             style.addProperty("fo:border-top", topBorderString, type);
1095             style.addProperty("calligra:specialborder-top", topBorderSpecialString, type);
1096         //if (bottomBorderStyle() != BorderNone)
1097             style.addProperty("fo:border-bottom", bottomBorderString, type);
1098             style.addProperty("calligra:specialborder-bottom", bottomBorderSpecialString, type);
1099     }
1100 
1101     if (style.type() != KoGenStyle::PageLayoutStyle) {
1102         //if (tlbrBorderStyle() != BorderNone) {
1103             style.addProperty("style:diagonal-tl-br", tlbrBorderString, type);
1104         //}
1105         //if (trblBorderStyle() != BorderNone) {
1106             style.addProperty("style:diagonal-bl-tr", trblBorderString, type);
1107         //}
1108     }
1109 
1110     // Handle double borders
1111     QString leftBorderLineWidth = QString("%1pt %2pt %3pt")
1112                                     .arg(QString::number(innerBorderWidth(LeftBorder)),
1113                                          QString::number(borderSpacing(LeftBorder)),
1114                                          QString::number(borderWidth(LeftBorder)));
1115     QString rightBorderLineWidth = QString("%1pt %2pt %3pt")
1116                                      .arg(QString::number(innerBorderWidth(RightBorder)),
1117                                           QString::number(borderSpacing(RightBorder)),
1118                                           QString::number(borderWidth(RightBorder)));
1119     QString topBorderLineWidth = QString("%1pt %2pt %3pt")
1120                                    .arg(QString::number(innerBorderWidth(TopBorder)),
1121                                         QString::number(borderSpacing(TopBorder)),
1122                                         QString::number(borderWidth(TopBorder)));
1123     QString bottomBorderLineWidth = QString("%1pt %2pt %3pt")
1124                                       .arg(QString::number(innerBorderWidth(BottomBorder)),
1125                                            QString::number(borderSpacing(BottomBorder)),
1126                                            QString::number(borderWidth(BottomBorder)));
1127 
1128     QString tlbrBorderLineWidth = QString("%1pt %2pt %3pt")
1129                                    .arg(QString::number(innerBorderWidth(TlbrBorder)),
1130                                         QString::number(borderSpacing(TlbrBorder)),
1131                                         QString::number(borderWidth(TlbrBorder)));
1132     QString trblBorderLineWidth = QString("%1pt %2pt %3pt")
1133                                       .arg(QString::number(innerBorderWidth(BltrBorder)),
1134                                            QString::number(borderSpacing(BltrBorder)),
1135                                            QString::number(borderWidth(BltrBorder)));
1136 
1137     if (leftBorderLineWidth == rightBorderLineWidth
1138         && leftBorderLineWidth == topBorderLineWidth
1139         && leftBorderLineWidth == bottomBorderLineWidth
1140         && borderStyle(LeftBorder) == borderStyle(RightBorder)
1141         && borderStyle(TopBorder) == borderStyle(BottomBorder)
1142         && borderStyle(TopBorder) == borderStyle(LeftBorder)
1143         && (borderStyle(LeftBorder) == BorderDouble || borderStyle(LeftBorder) == BorderDoubleWave)) {
1144         style.addProperty("style:border-line-width", leftBorderLineWidth, type);
1145     } else {
1146         if (borderStyle(LeftBorder) == BorderDouble || borderStyle(LeftBorder) == BorderDoubleWave)
1147             style.addProperty("style:border-line-width-left", leftBorderLineWidth, type);
1148         if (borderStyle(RightBorder) == BorderDouble || borderStyle(RightBorder) == BorderDoubleWave)
1149             style.addProperty("style:border-line-width-right", rightBorderLineWidth, type);
1150         if (borderStyle(TopBorder) == BorderDouble || borderStyle(TopBorder) == BorderDoubleWave)
1151             style.addProperty("style:border-line-width-top", topBorderLineWidth, type);
1152         if (borderStyle(BottomBorder) == BorderDouble || borderStyle(BottomBorder) == BorderDoubleWave)
1153             style.addProperty("style:border-line-width-bottom", bottomBorderLineWidth, type);
1154     }
1155 
1156     if (style.type() != KoGenStyle::PageLayoutStyle) {
1157         if (borderStyle(TlbrBorder) == BorderDouble || borderStyle(TlbrBorder) == BorderDoubleWave) {
1158             style.addProperty("style:diagonal-tl-br-widths", tlbrBorderLineWidth, type);
1159         }
1160         if (borderStyle(BltrBorder) == BorderDouble || borderStyle(BltrBorder) == BorderDoubleWave) {
1161             style.addProperty("style:diagonal-bl-tr-widths", trblBorderLineWidth, type);
1162         }
1163     }
1164 }
1165