Warning, file /office/calligra/libs/odf/KoBorder.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  *
0003  * Copyright (C) 2009 Inge Wallin <inge@lysator.liu.se>
0004  * Copyright (C) 2009 Thomas Zander <zander@kde.org>
0005  * Copyright (C) 2011 Pierre Ducroquet <pinaraf@pinaraf.info>
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public License
0018  * along with this library; see the file COPYING.LIB.  If not, write to
0019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  */
0022 
0023 #include "KoBorder.h"
0024 
0025 #include <QPainter>
0026 
0027 #include <OdfDebug.h>
0028 
0029 #include <KoUnit.h>
0030 #include <KoXmlNS.h>
0031 #include <KoXmlReader.h>
0032 #include <KoStyleStack.h>
0033 
0034 
0035 class KoBorderPrivate : public QSharedData
0036 {
0037 public:
0038     KoBorderPrivate();
0039     ~KoBorderPrivate();
0040 
0041     QMap<KoBorder::BorderSide, KoBorder::BorderData> data;
0042 };
0043 
0044 KoBorderPrivate::KoBorderPrivate()
0045 {
0046 }
0047 
0048 KoBorderPrivate::~KoBorderPrivate()
0049 {
0050 }
0051 
0052 KoBorder::BorderData::BorderData()
0053     : style(KoBorder::BorderNone)
0054     , outerPen(QPen())
0055     , innerPen(QPen())
0056     , spacing(0)
0057 {
0058     outerPen.setWidthF(0.0f);
0059     innerPen.setWidthF(0.0f);
0060 }
0061 
0062 bool KoBorder::BorderData::operator==(const KoBorder::BorderData& other) const
0063 {
0064     // Left Borders
0065     if (style == BorderNone && other.style == BorderNone) {
0066         // If both styles are None, then the rest of the values don't
0067         // need to be compared.
0068         ;
0069     }
0070     else if (style != other.style) {
0071         // If any of them are non-None, and they are different, the
0072         // borders are also different.
0073         return false;
0074     }
0075     else {
0076         // Here we know that the border styles are the same, now
0077         // compare the rest of the values.
0078         if (outerPen != other.outerPen)
0079             return false;
0080 
0081         // If the border style == BorderDouble, then compare a couple
0082         // of other values too.
0083         if (style == BorderDouble) {
0084             if (innerPen != other.innerPen)
0085                 return false;
0086             if (spacing != other.spacing)
0087                 return false;
0088         }
0089     }
0090 
0091     return true;
0092 }
0093 
0094 // ----------------------------------------------------------------
0095 
0096 KoBorder::KoBorder()
0097     : d(new KoBorderPrivate)
0098 {
0099 }
0100 
0101 KoBorder::KoBorder(const KoBorder &kb)
0102     : d(kb.d)
0103 {
0104 }
0105 
0106 KoBorder::~KoBorder()
0107 {
0108     // No delete because d is a QSharedDataPointer.
0109 }
0110 
0111 
0112 // ----------------------------------------------------------------
0113 //                             operators
0114 
0115 KoBorder &KoBorder::operator=(const KoBorder &other)
0116 {
0117     d = other.d;
0118 
0119     return *this;
0120 }
0121 
0122 bool KoBorder::operator==(const KoBorder &other) const
0123 {
0124     if (d.data() == other.d.data())
0125         return true;
0126 
0127 
0128     if (d->data.size() != other.d->data.size())
0129         return false;
0130 
0131     for (auto i = d->data.constBegin(); i != d->data.constEnd(); ++i) {
0132         if (!other.d->data.contains(i.key()))
0133             return false;
0134         if (!(other.d->data[i.key()] == i.value()))
0135             return false;
0136     }
0137 
0138     return true;
0139 }
0140 
0141 
0142 // ----------------------------------------------------------------
0143 //                 public, non-class functions
0144 
0145 KoBorder::BorderStyle KoBorder::odfBorderStyle(const QString &borderstyle, bool *converted)
0146 {
0147     // Note: the styles marked "Not odf compatible" below are legacies
0148     //       from the old words format.  There are also lots of border
0149     //       styles in the MS DOC that we may have to handle at some point.
0150     if (converted)
0151         *converted = true;
0152     if (borderstyle == "none")
0153         return BorderNone;
0154     if (borderstyle == "solid")
0155         return BorderSolid;
0156     if (borderstyle == "dashed")
0157         return BorderDashed;
0158     if (borderstyle == "dotted")
0159         return BorderDotted;
0160     if (borderstyle == "dot-dash")
0161         return BorderDashDot;
0162     if (borderstyle == "dot-dot-dash")
0163         return BorderDashDotDot;
0164     if (borderstyle == "double")
0165         return BorderDouble;
0166     if (borderstyle == "groove")   // Not odf compatible -- see above
0167         return BorderGroove;
0168     if (borderstyle == "ridge")   // Not odf compatible -- see above
0169         return BorderRidge;
0170     if (borderstyle == "inset")   // Not odf compatible -- see above
0171         return BorderInset;
0172     if (borderstyle == "outset")   // Not odf compatible -- see above
0173         return BorderOutset;
0174     if (borderstyle == "dash-largegap")
0175         return KoBorder::BorderDashedLong;
0176     if (borderstyle == "slash") // not officially odf, but we support it anyway
0177         return KoBorder::BorderSlash;
0178     if (borderstyle == "wave") // not officially odf, but we support it anyway
0179         return KoBorder::BorderWave;
0180     if (borderstyle == "double-wave") // not officially odf, but we support it anyway
0181         return KoBorder::BorderDoubleWave;
0182 
0183     if (converted)
0184         *converted = false;
0185 
0186     return BorderSolid;
0187 }
0188 
0189 QString KoBorder::odfBorderStyleString(BorderStyle borderstyle)
0190 {
0191     switch (borderstyle) {
0192     case BorderDashed:
0193         return QString("dashed");
0194     case BorderDotted:
0195         return QString("dotted");
0196     case BorderDashDot:
0197         return QString("dot-dash");
0198     case BorderDashDotDot:
0199         return QString("dot-dot-dash");
0200     case BorderDouble:
0201         return QString("double");
0202     case BorderGroove:
0203         return QString("groove"); // not odf -- see above
0204     case BorderRidge:
0205         return QString("ridge"); // not odf -- see above
0206     case BorderInset:
0207         return QString("inset"); // not odf -- see above
0208     case BorderOutset:
0209         return QString("outset"); // not odf -- see above
0210     case BorderSolid:
0211         return QString("solid");
0212     case BorderNone:
0213         return QString("none");
0214 
0215     default:
0216         // Handle unknown types as solid.
0217         return QString("solid");
0218     }
0219 }
0220 
0221 QString KoBorder::msoBorderStyleString(BorderStyle borderstyle)
0222 {
0223     switch (borderstyle) {
0224     case KoBorder::BorderDashedLong:
0225         return QString("dash-largegap");
0226     case KoBorder::BorderSlash:
0227         return QString("slash"); // not officially odf, but we support it anyway
0228     case KoBorder::BorderWave:
0229         return QString("wave"); // not officially odf, but we support it anyway
0230     case KoBorder::BorderDoubleWave:
0231         return QString("double-wave"); // not officially odf, but we support it anyway
0232 
0233     default:
0234         // Handle remaining styles as odf type style.
0235         return odfBorderStyleString(borderstyle);
0236     }
0237 }
0238 
0239 
0240 // ----------------------------------------------------------------
0241 //                         Getters and Setters
0242 
0243 
0244 void KoBorder::setBorderStyle(BorderSide side, BorderStyle style)
0245 {
0246     if (d->data[side].style == style) {
0247         return;
0248     }
0249 
0250     if (!d->data.contains(side)) {
0251         BorderData data;
0252         data.style = style;
0253         d->data[side] = data;
0254     } else {
0255         d->data[side].style = style;
0256     }
0257 
0258     // Make a best effort to create the best possible dash pattern for the chosen style.
0259     // FIXME: KoTableCellStyle::setEdge() should call this function.
0260     BorderData &edge = d->data[side];
0261     qreal width = edge.outerPen.widthF();
0262     qreal innerWidth = 0;
0263     qreal middleWidth = 0;
0264     qreal space = 0;
0265     QVector<qreal> dashes;
0266     switch (style) {
0267     case KoBorder::BorderNone:
0268         width = 0.0;
0269         break;
0270     case KoBorder::BorderDouble:
0271         innerWidth = space = edge.outerPen.width() / 3; //some nice default look
0272         width -= (space + innerWidth);
0273         edge.outerPen.setStyle(Qt::SolidLine);
0274         break;
0275     case KoBorder::BorderDotted:
0276         dashes << 1 << 1;
0277         edge.outerPen.setDashPattern(dashes);
0278         break;
0279     case KoBorder::BorderDashed:
0280         dashes << 4 << 1;
0281         edge.outerPen.setDashPattern(dashes);
0282         break;
0283     case KoBorder::BorderDashedLong: {
0284         dashes << 4 << 4;
0285         edge.outerPen.setDashPattern(dashes);
0286         break;
0287     }
0288     case KoBorder::BorderTriple:
0289         innerWidth = middleWidth = space = width/6;
0290         width -= (space + innerWidth);
0291         edge.outerPen.setStyle(Qt::SolidLine);
0292         break;
0293     case KoBorder::BorderDashDot:
0294         dashes << 3 << 3<< 7 << 3;
0295         edge.outerPen.setDashPattern(dashes);
0296         break;
0297     case KoBorder::BorderDashDotDot:
0298         dashes << 2 << 2<< 6 << 2 << 2 << 2;
0299         edge.outerPen.setDashPattern(dashes);
0300         break;
0301     case KoBorder::BorderWave:
0302         edge.outerPen.setStyle(Qt::SolidLine);
0303         break;
0304     case KoBorder::BorderSlash:
0305         edge.outerPen.setStyle(Qt::SolidLine);
0306         break;
0307     case KoBorder::BorderDoubleWave:
0308         innerWidth = space = width/3; //some nice default look
0309         width -= (space + innerWidth);
0310         edge.outerPen.setStyle(Qt::SolidLine);
0311         break;
0312     default:
0313         edge.outerPen.setStyle(Qt::SolidLine);
0314         break;
0315     }
0316     edge.outerPen.setJoinStyle(Qt::MiterJoin);
0317     edge.outerPen.setCapStyle(Qt::FlatCap);
0318     edge.outerPen.setWidthF(width);
0319 
0320     edge.spacing = space;
0321     edge.innerPen = edge.outerPen;
0322     edge.innerPen.setWidthF(innerWidth);
0323 }
0324 
0325 KoBorder::BorderStyle KoBorder::borderStyle(BorderSide side) const
0326 {
0327     if (!d->data.contains(side)) {
0328         return BorderNone;
0329     } else {
0330         return d->data[side].style;
0331     }
0332 }
0333 
0334 void KoBorder::setBorderColor(BorderSide side, const QColor &color)
0335 {
0336     if (!d->data.contains(side)) {
0337         BorderData data;
0338         data.outerPen.setColor(color);
0339         d->data[side] = data;
0340     } else {
0341         d->data[side].outerPen.setColor(color);
0342     }
0343 }
0344 
0345 QColor KoBorder::borderColor(BorderSide side) const
0346 {
0347     if (!d->data.contains(side)) {
0348         return QColor();
0349     } else {
0350         return d->data[side].outerPen.color();
0351     }
0352 }
0353 
0354 void KoBorder::setBorderWidth(BorderSide side, qreal width)
0355 {
0356     if (!d->data.contains(side)) {
0357         BorderData data;
0358         data.outerPen.setWidthF(width);
0359         d->data[side] = data;
0360     } else {
0361         d->data[side].outerPen.setWidthF(width);
0362     }
0363 }
0364 
0365 qreal KoBorder::borderWidth(BorderSide side) const
0366 {
0367     if (!d->data.contains(side)) {
0368         return 0;
0369     } else {
0370         if (d->data[side].style == BorderDouble)
0371             return (d->data[side].outerPen.widthF() + d->data[side].innerPen.widthF()
0372                     + d->data[side].spacing);
0373         else
0374             return d->data[side].outerPen.widthF();
0375     }
0376 }
0377 
0378 void KoBorder::setOuterBorderWidth(BorderSide side, qreal width)
0379 {
0380     if (!d->data.contains(side)) {
0381         BorderData data;
0382         data.outerPen.setWidthF(width);
0383         d->data[side] = data;
0384     } else {
0385         d->data[side].outerPen.setWidthF(width);
0386     }
0387 }
0388 
0389 qreal KoBorder::outerBorderWidth(BorderSide side) const
0390 {
0391     if (!d->data.contains(side)) {
0392         return 0;
0393     } else {
0394         return d->data[side].outerPen.widthF();
0395     }
0396 }
0397 
0398 void KoBorder::setInnerBorderWidth(BorderSide side, qreal width)
0399 {
0400     if (!d->data.contains(side)) {
0401         BorderData data;
0402         data.innerPen.setWidthF(width);
0403         d->data[side] = data;
0404     } else {
0405         d->data[side].innerPen.setWidthF(width);
0406     }
0407 }
0408 
0409 qreal KoBorder::innerBorderWidth(BorderSide side) const
0410 {
0411     if (!d->data.contains(side)) {
0412         return 0;
0413     } else {
0414         return d->data[side].innerPen.widthF();
0415     }
0416 }
0417 
0418 void KoBorder::setBorderSpacing(BorderSide side, qreal width)
0419 {
0420     if (!d->data.contains(side)) {
0421         BorderData data;
0422         data.spacing = width;
0423         d->data[side] = data;
0424     } else {
0425         d->data[side].spacing = width;
0426     }
0427 }
0428 
0429 qreal KoBorder::borderSpacing(BorderSide side) const
0430 {
0431     if (!d->data.contains(side)) {
0432         return 0;
0433     } else {
0434         return d->data[side].spacing;
0435     }
0436 }
0437 
0438 
0439 KoBorder::BorderData KoBorder::borderData(BorderSide side) const
0440 {
0441     return d->data.value(side, BorderData());
0442 }
0443 
0444 void KoBorder::setBorderData(BorderSide side, const BorderData &data)
0445 {
0446     d->data[side] = data;
0447 }
0448 
0449 
0450 // -------------------------------
0451 
0452 bool KoBorder::hasBorder() const
0453 {
0454     if (borderStyle(LeftBorder) != BorderNone && borderWidth(LeftBorder) > 0.0)
0455         return true;
0456     if (borderStyle(RightBorder) != BorderNone && borderWidth(RightBorder) > 0.0)
0457         return true;
0458     if (borderStyle(TopBorder) != BorderNone && borderWidth(TopBorder) > 0.0)
0459         return true;
0460     if (borderStyle(BottomBorder) != BorderNone && borderWidth(BottomBorder) > 0.0)
0461         return true;
0462     if (borderStyle(TlbrBorder) != BorderNone && borderWidth(TlbrBorder) > 0.0)
0463         return true;
0464     if (borderStyle(BltrBorder) != BorderNone && borderWidth(BltrBorder) > 0.0)
0465         return true;
0466     return false;
0467 }
0468 
0469 bool KoBorder::hasBorder(KoBorder::BorderSide side) const
0470 {
0471     return borderStyle(side) != BorderNone && borderWidth(side) > 0.0;
0472 }
0473 
0474 
0475 // ----------------------------------------------------------------
0476 //                         painting
0477 
0478 
0479 void KoBorder::paint(QPainter &painter, const QRectF &borderRect,
0480                      BorderPaintArea whereToPaint) const
0481 {
0482     Q_UNUSED(whereToPaint);
0483     // In tables it is apparently best practice to paint the
0484     // horizontal lines over the vertical ones.  So let's use the same
0485     // strategy here.
0486 
0487     QPointF start;
0488     QPointF end;
0489 
0490     // FIXME: Make KoBorder store pointers to BorderData instead.  This is very inefficient.
0491     BorderData leftEdge = borderData(KoBorder::LeftBorder);
0492     BorderData rightEdge = borderData(KoBorder::RightBorder);
0493     BorderData topEdge = borderData(KoBorder::TopBorder);
0494     BorderData bottomEdge = borderData(KoBorder::BottomBorder);
0495 
0496     // Left border
0497     if (hasBorder(LeftBorder)) {
0498         start = borderRect.topLeft();
0499         end   = borderRect.bottomLeft();
0500         paintBorderSide(painter, start, end, &leftEdge, true,
0501                         hasBorder(TopBorder) ? &topEdge : 0,
0502                         hasBorder(BottomBorder) ? &bottomEdge : 0,
0503                         1);
0504     }
0505 
0506     // Right border
0507     if (hasBorder(RightBorder)) {
0508         start = borderRect.topRight();
0509         end   = borderRect.bottomRight();
0510         paintBorderSide(painter, start, end, &rightEdge, true,
0511                         hasBorder(TopBorder) ? &topEdge : 0,
0512                         hasBorder(BottomBorder) ? &bottomEdge : 0,
0513                         -1);
0514     }
0515 
0516     // Top border
0517     if (hasBorder(TopBorder)) {
0518         start = borderRect.topLeft();
0519         end   = borderRect.topRight();
0520         paintBorderSide(painter, start, end, &topEdge, false,
0521                         hasBorder(LeftBorder) ? &leftEdge : 0,
0522                         hasBorder(RightBorder) ? &rightEdge : 0,
0523                         1);
0524     }
0525 
0526     // Bottom border
0527     if (hasBorder(BottomBorder)) {
0528         start = borderRect.bottomLeft();
0529         end   = borderRect.bottomRight();
0530         paintBorderSide(painter, start, end, &bottomEdge, false,
0531                         hasBorder(LeftBorder) ? &leftEdge : 0,
0532                         hasBorder(RightBorder) ? &rightEdge : 0,
0533                         -1);
0534     }
0535 
0536     // FIXME: Diagonal borders
0537 }
0538 
0539 void KoBorder::paintBorderSide(QPainter &painter, QPointF lineStart, QPointF lineEnd,
0540                                BorderData *borderData, bool isVertical,
0541                                BorderData *neighbour1, BorderData *neighbour2,
0542                                int inwardsAcross) const
0543 {
0544     // Adjust the outer line so that it is inside the boundary.
0545     qreal displacement = borderData->outerPen.widthF() / qreal(2.0);
0546     if (isVertical) {
0547         lineStart.setX(lineStart.x() + inwardsAcross * displacement);
0548         lineEnd.setX(lineEnd.x() + inwardsAcross * displacement);
0549     }
0550     else {
0551         lineStart.setY(lineStart.y() + inwardsAcross * displacement);
0552         lineEnd.setY(lineEnd.y() + inwardsAcross * displacement);
0553     }
0554 
0555     painter.setPen(borderData->outerPen);
0556     painter.drawLine(lineStart, lineEnd);
0557 
0558     if (borderData->style == BorderDouble) {
0559         displacement = (borderData->outerPen.widthF() / qreal(2.0)
0560                         + borderData->spacing
0561                         + borderData->innerPen.widthF() / qreal(2.0));
0562         if (isVertical) {
0563             lineStart.setX(lineStart.x() + inwardsAcross * displacement);
0564             lineEnd.setX(lineEnd.x() + inwardsAcross * displacement);
0565         }
0566         else {
0567             lineStart.setY(lineStart.y() + inwardsAcross * displacement);
0568             lineEnd.setY(lineEnd.y() + inwardsAcross * displacement);
0569         }
0570 
0571         // Adjust for neigboring inner lines.
0572         if (neighbour1 && neighbour1->style == BorderDouble) {
0573             displacement = neighbour1->outerPen.widthF() + neighbour1->spacing;
0574             if (isVertical) {
0575                 lineStart.setY(lineStart.y() + displacement);
0576             }
0577             else {
0578                 lineStart.setX(lineStart.x() + displacement);
0579             }
0580         }
0581         if (neighbour2 && neighbour2->style == BorderDouble) {
0582             displacement = neighbour2->outerPen.widthF() + neighbour2->spacing;
0583             if (isVertical) {
0584                 lineEnd.setY(lineEnd.y() - displacement);
0585             }
0586             else {
0587                 lineEnd.setX(lineEnd.x() - displacement);
0588             }
0589         }
0590 
0591         // Draw the inner line.
0592         painter.setPen(borderData->innerPen);
0593         painter.drawLine(lineStart, lineEnd);
0594     }
0595 }
0596 
0597 
0598 // ----------------------------------------------------------------
0599 //                         static functions
0600 
0601 
0602 void parseOdfBorder(const QString &border, QColor *color,
0603                     KoBorder::BorderStyle *borderStyle, bool *hasBorderStyle,
0604                     qreal *borderWidth, bool *hasBorderWidth)
0605 {
0606     *hasBorderStyle = false;
0607     *hasBorderWidth = false;
0608 
0609     if (!border.isEmpty() && border != "none" && border != "hidden") {
0610         QStringList borderData = border.split(' ', QString::SkipEmptyParts);
0611         if (borderData.length() > 0)
0612         {
0613             const QColor borderColor = QColor(borderData.last());
0614             if (borderColor.isValid()) {
0615                 *color = borderColor;
0616                 borderData.removeLast();
0617             }
0618 
0619             bool converted = false;
0620             const KoBorder::BorderStyle parsedBorderStyle = KoBorder::odfBorderStyle(borderData.last(), &converted);
0621             if (converted) {
0622                 *hasBorderStyle = true;
0623                 borderData.removeLast();
0624                 *borderStyle = parsedBorderStyle;
0625             }
0626 
0627             if (!borderData.isEmpty()) {
0628                 const qreal parsedBorderWidth = KoUnit::parseValue(borderData[0], 1.0);
0629                 *borderWidth = parsedBorderWidth;
0630                 *hasBorderWidth = true;
0631             }
0632         }
0633     }
0634 }
0635 
0636 // ----------------------------------------------------------------
0637 //                         load and save
0638 
0639 bool KoBorder::loadOdf(const KoXmlElement &style)
0640 {
0641     bool result = false;
0642 
0643     QString borderString;
0644     bool hasSpecialBorder;
0645     QString specialBorderString;
0646     if (style.hasAttributeNS(KoXmlNS::fo, "border")) {
0647         borderString = style.attributeNS(KoXmlNS::fo, "border");
0648         if (borderString == "none") {
0649             // We use the "false" to indicate that there is no border
0650             // rather than that the parsing has failed.
0651             return false;
0652         }
0653 
0654         result = true;
0655         if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder"))) {
0656             specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder");
0657         }
0658         parseAndSetBorder(borderString, hasSpecialBorder, specialBorderString);
0659     }
0660     else {
0661         // No common border attributes, check for the individual ones.
0662         if (style.hasAttributeNS(KoXmlNS::fo, "border-left")) {
0663             result = true;
0664             borderString = style.attributeNS(KoXmlNS::fo, "border-left");
0665             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-left"))) {
0666                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-left");
0667             }
0668             parseAndSetBorder(LeftBorder, borderString, hasSpecialBorder, specialBorderString);
0669         }
0670         if (style.hasAttributeNS(KoXmlNS::fo, "border-top")) {
0671             result = true;
0672             borderString = style.attributeNS(KoXmlNS::fo, "border-top");
0673             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-top"))) {
0674                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-top");
0675             }
0676             parseAndSetBorder(TopBorder, borderString, hasSpecialBorder, specialBorderString);
0677         }
0678         if (style.hasAttributeNS(KoXmlNS::fo, "border-right")) {
0679             result = true;
0680             borderString = style.attributeNS(KoXmlNS::fo, "border-right");
0681             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-right"))) {
0682                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-right");
0683             }
0684             parseAndSetBorder(RightBorder, borderString, hasSpecialBorder, specialBorderString);
0685         }
0686         if (style.hasAttributeNS(KoXmlNS::fo, "border-bottom")) {
0687             result = true;
0688             borderString = style.attributeNS(KoXmlNS::fo, "border-bottom");
0689             if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-bottom"))) {
0690                 specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-bottom");
0691             }
0692             parseAndSetBorder(BottomBorder, borderString, hasSpecialBorder, specialBorderString);
0693         }
0694     }
0695 
0696     // Diagonals are treated individually and are NOT part of <style:border>.
0697     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-tl-br")) {
0698         result = true;
0699         borderString = style.attributeNS(KoXmlNS::fo, "border-tl-br");
0700         if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-tl-br"))) {
0701             specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-tl-br");
0702         }
0703         parseAndSetBorder(TlbrBorder, borderString, hasSpecialBorder, specialBorderString);
0704     }
0705     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-bl-tr")) {
0706         result = true;
0707         borderString = style.attributeNS(KoXmlNS::fo, "border-bl-tr");
0708         if ((hasSpecialBorder = style.hasAttributeNS(KoXmlNS::calligra, "specialborder-bl-tr"))) {
0709             specialBorderString = style.attributeNS(KoXmlNS::calligra, "specialborder-bl-tr");
0710         }
0711         parseAndSetBorder(BltrBorder, borderString, hasSpecialBorder, specialBorderString);
0712     }
0713 
0714     // Handle double borders.
0715     if (style.hasAttributeNS(KoXmlNS::style, "border-line-width")) {
0716         result = true;
0717         QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width");
0718         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0719             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0720             setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
0721             setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
0722             setOuterBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
0723 
0724             setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
0725             setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
0726             setOuterBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
0727 
0728             setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
0729             setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
0730             setOuterBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
0731 
0732             setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
0733             setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
0734             setOuterBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
0735         }
0736     }
0737     else {
0738         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-left")) {
0739             result = true;
0740             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-left");
0741             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0742                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0743                 setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
0744                 setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
0745                 setOuterBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
0746             }
0747         }
0748         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-top")) {
0749             result = true;
0750             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-top");
0751             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0752                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0753                 setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
0754                 setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
0755                 setOuterBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
0756             }
0757         }
0758         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-right")) {
0759             result = true;
0760             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-right");
0761             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0762                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0763                 setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
0764                 setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
0765                 setOuterBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
0766             }
0767         }
0768         if (style.hasAttributeNS(KoXmlNS::style, "border-line-width-bottom")) {
0769             result = true;
0770             QString borderLineWidth = style.attributeNS(KoXmlNS::style, "border-line-width-bottom");
0771             if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0772                 QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0773                 setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
0774                 setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
0775                 setOuterBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
0776             }
0777         }
0778     }
0779 
0780     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-tl-br-widths")) {
0781         result = true;
0782         QString borderLineWidth = style.attributeNS(KoXmlNS::style, "diagonal-tl-br-widths");
0783         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0784             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0785             setInnerBorderWidth(TlbrBorder, KoUnit::parseValue(blw[0], 0.1));
0786             setBorderSpacing(TlbrBorder, KoUnit::parseValue(blw[1], 1.0));
0787             setOuterBorderWidth(TlbrBorder, KoUnit::parseValue(blw[2], 0.1));
0788         }
0789     }
0790     if (style.hasAttributeNS(KoXmlNS::style, "diagonal-bl-tr-widths")) {
0791         result = true;
0792         QString borderLineWidth = style.attributeNS(KoXmlNS::style, "diagonal-bl-tr-widths");
0793         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0794             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0795             setInnerBorderWidth(BltrBorder, KoUnit::parseValue(blw[0], 0.1));
0796             setBorderSpacing(BltrBorder, KoUnit::parseValue(blw[1], 1.0));
0797             setOuterBorderWidth(BltrBorder, KoUnit::parseValue(blw[2], 0.1));
0798         }
0799     }
0800     return result;
0801 }
0802 
0803 bool KoBorder::loadOdf(const KoStyleStack &styleStack)
0804 {
0805     bool result = false;
0806 
0807     QString borderString;
0808     bool hasSpecialBorder;
0809     QString specialBorderString;
0810     if (styleStack.hasProperty(KoXmlNS::fo, "border")) {
0811         result = true;
0812         borderString = styleStack.property(KoXmlNS::fo, "border");
0813         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder"))) {
0814             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder");
0815         }
0816         parseAndSetBorder(borderString, hasSpecialBorder, specialBorderString);
0817     }
0818 
0819     // Even if there are common border attributes, check for the
0820     // individual ones since they have precedence.
0821 
0822     if (styleStack.hasProperty(KoXmlNS::fo, "border-left")) {
0823         result = true;
0824         borderString = styleStack.property(KoXmlNS::fo, "border-left");
0825         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-left"))) {
0826             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-left");
0827         }
0828         parseAndSetBorder(LeftBorder, borderString, hasSpecialBorder, specialBorderString);
0829     }
0830     if (styleStack.hasProperty(KoXmlNS::fo, "border-top")) {
0831         result = true;
0832         borderString = styleStack.property(KoXmlNS::fo, "border-top");
0833         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-top"))) {
0834             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-top");
0835         }
0836         parseAndSetBorder(TopBorder, borderString, hasSpecialBorder, specialBorderString);
0837     }
0838     if (styleStack.hasProperty(KoXmlNS::fo, "border-right")) {
0839         result = true;
0840         borderString = styleStack.property(KoXmlNS::fo, "border-right");
0841         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-right"))) {
0842             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-right");
0843         }
0844         parseAndSetBorder(RightBorder, borderString, hasSpecialBorder, specialBorderString);
0845 
0846     }
0847     if (styleStack.hasProperty(KoXmlNS::fo, "border-bottom")) {
0848         result = true;
0849         borderString = styleStack.property(KoXmlNS::fo, "border-bottom");
0850         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-bottom"))) {
0851             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-bottom");
0852         }
0853         parseAndSetBorder(BottomBorder, borderString, hasSpecialBorder, specialBorderString);
0854     }
0855 
0856     // Diagonals are treated individually and are NOT part of <style:border>.
0857     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-tl-br")) {
0858         result = true;
0859         borderString = styleStack.property(KoXmlNS::fo, "border-tl-br");
0860         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-tl-br"))) {
0861             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-tl-br");
0862         }
0863         parseAndSetBorder(TlbrBorder, borderString, hasSpecialBorder, specialBorderString);
0864     }
0865     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-bl-tr")) {
0866         result = true;
0867         borderString = styleStack.property(KoXmlNS::fo, "border-bl-tr");
0868         if ((hasSpecialBorder = styleStack.hasProperty(KoXmlNS::calligra, "specialborder-bl-tr"))) {
0869             specialBorderString = styleStack.property(KoXmlNS::calligra, "specialborder-bl-tr");
0870         }
0871         parseAndSetBorder(BltrBorder, borderString, hasSpecialBorder, specialBorderString);
0872     }
0873 
0874     // Handle double borders.
0875     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width")) {
0876         result = true;
0877         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width");
0878         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0879             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0880             setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
0881             setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
0882             setOuterBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
0883 
0884             setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
0885             setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
0886             setOuterBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
0887 
0888             setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
0889             setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
0890             setOuterBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
0891 
0892             setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
0893             setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
0894             setOuterBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
0895         }
0896     }
0897     // Even if there are common border attributes, check for the
0898     // individual ones since they have precedence.
0899 
0900     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-left")) {
0901         result = true;
0902         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-left");
0903         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0904             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0905             setInnerBorderWidth(LeftBorder, KoUnit::parseValue(blw[0], 0.1));
0906             setBorderSpacing(LeftBorder, KoUnit::parseValue(blw[1], 1.0));
0907             setOuterBorderWidth(LeftBorder, KoUnit::parseValue(blw[2], 0.1));
0908         }
0909     }
0910     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-top")) {
0911         result = true;
0912         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-top");
0913         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0914             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0915             setInnerBorderWidth(TopBorder, KoUnit::parseValue(blw[0], 0.1));
0916             setBorderSpacing(TopBorder, KoUnit::parseValue(blw[1], 1.0));
0917             setOuterBorderWidth(TopBorder, KoUnit::parseValue(blw[2], 0.1));
0918         }
0919     }
0920     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-right")) {
0921         result = true;
0922         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-right");
0923         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0924             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0925             setInnerBorderWidth(RightBorder, KoUnit::parseValue(blw[0], 0.1));
0926             setBorderSpacing(RightBorder, KoUnit::parseValue(blw[1], 1.0));
0927             setOuterBorderWidth(RightBorder, KoUnit::parseValue(blw[2], 0.1));
0928         }
0929     }
0930     if (styleStack.hasProperty(KoXmlNS::style, "border-line-width-bottom")) {
0931         result = true;
0932         QString borderLineWidth = styleStack.property(KoXmlNS::style, "border-line-width-bottom");
0933         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0934             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0935             setInnerBorderWidth(BottomBorder, KoUnit::parseValue(blw[0], 0.1));
0936             setBorderSpacing(BottomBorder, KoUnit::parseValue(blw[1], 1.0));
0937             setOuterBorderWidth(BottomBorder, KoUnit::parseValue(blw[2], 0.1));
0938         }
0939     }
0940 
0941     // Diagonals are treated individually and are NOT part of <style:border>.
0942     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-tl-br-widths")) {
0943         result = true;
0944         QString borderLineWidth = styleStack.property(KoXmlNS::style, "diagonal-tl-br-widths");
0945         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0946             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0947             setInnerBorderWidth(TlbrBorder, KoUnit::parseValue(blw[0], 0.1));
0948             setBorderSpacing(TlbrBorder, KoUnit::parseValue(blw[1], 1.0));
0949             setOuterBorderWidth(TlbrBorder, KoUnit::parseValue(blw[2], 0.1));
0950         }
0951     }
0952     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-bl-tr-widths")) {
0953         result = true;
0954         QString borderLineWidth = styleStack.property(KoXmlNS::style, "diagonal-bl-tr-widths");
0955         if (!borderLineWidth.isEmpty() && borderLineWidth != "none" && borderLineWidth != "hidden") {
0956             QStringList blw = borderLineWidth.split(' ', QString::SkipEmptyParts);
0957             setInnerBorderWidth(BltrBorder, KoUnit::parseValue(blw[0], 0.1));
0958             setBorderSpacing(BltrBorder, KoUnit::parseValue(blw[1], 1.0));
0959             setOuterBorderWidth(BltrBorder, KoUnit::parseValue(blw[2], 0.1));
0960         }
0961     }
0962 
0963     return result;
0964 }
0965 
0966 
0967 // Private
0968 void KoBorder::parseAndSetBorder(const QString &borderString,
0969                                  bool hasSpecialBorder, const QString &specialBorderString)
0970 {
0971     if (borderString == "none") {
0972         return;
0973     }
0974 
0975     //debugOdf << "*** *** Found border: " << border;
0976     QColor bordersColor;
0977     BorderStyle bordersStyle;
0978     qreal bordersWidth;
0979     bool foundStyle;
0980     bool foundWidth;
0981     parseOdfBorder(borderString, &bordersColor, &bordersStyle, &foundStyle,
0982                    &bordersWidth, &foundWidth);
0983     if (bordersColor.isValid()) {
0984         setBorderColor(LeftBorder, bordersColor);
0985         setBorderColor(TopBorder, bordersColor);
0986         setBorderColor(RightBorder, bordersColor);
0987         setBorderColor(BottomBorder, bordersColor);
0988     }
0989     if (hasSpecialBorder) {
0990         bordersStyle = KoBorder::odfBorderStyle(specialBorderString, &foundStyle);
0991     }
0992 
0993     if (foundStyle) {
0994         setBorderStyle(LeftBorder, bordersStyle);
0995         setBorderStyle(TopBorder, bordersStyle);
0996         setBorderStyle(RightBorder, bordersStyle);
0997         setBorderStyle(BottomBorder, bordersStyle);
0998     }
0999     if (foundWidth) {
1000         setBorderWidth(LeftBorder, bordersWidth);
1001         setBorderWidth(TopBorder, bordersWidth);
1002         setBorderWidth(RightBorder, bordersWidth);
1003         setBorderWidth(BottomBorder, bordersWidth);
1004     }
1005 }
1006 
1007 // Private
1008 void KoBorder::parseAndSetBorder(const BorderSide borderSide, const QString &borderString,
1009                                  bool hasSpecialBorder, const QString &specialBorderString)
1010 {
1011     QColor borderColor;
1012     BorderStyle borderStyle;
1013     qreal borderWidth;
1014     bool foundStyle;
1015     bool foundWidth;
1016 
1017     parseOdfBorder(borderString, &borderColor, &borderStyle, &foundStyle,
1018                    &borderWidth, &foundWidth);
1019     if (borderColor.isValid()) {
1020         setBorderColor(borderSide, borderColor);
1021     }
1022     if (hasSpecialBorder) {
1023         borderStyle = KoBorder::odfBorderStyle(specialBorderString, &foundStyle);
1024     }
1025 
1026     if (foundStyle) {
1027         setBorderStyle( borderSide, borderStyle);
1028     }
1029     if (foundWidth) {
1030         setBorderWidth( borderSide, borderWidth);
1031     }
1032 }
1033 
1034 void KoBorder::saveOdf(KoGenStyle &style, KoGenStyle::PropertyType type) const
1035 {
1036     // Get the strings that describe respective borders.
1037     QString leftBorderString = QString("%1pt %2 %3")
1038                                  .arg(QString::number(borderWidth(LeftBorder)),
1039                                       odfBorderStyleString(borderStyle(LeftBorder)),
1040                                       borderColor(LeftBorder).name());
1041     QString rightBorderString =  QString("%1pt %2 %3")
1042                                   .arg(QString::number(borderWidth(RightBorder)),
1043                                        odfBorderStyleString(borderStyle(RightBorder)),
1044                                        borderColor(RightBorder).name());
1045     QString topBorderString = QString("%1pt %2 %3")
1046                                 .arg(QString::number(borderWidth(TopBorder)),
1047                                      odfBorderStyleString(borderStyle(TopBorder)),
1048                                      borderColor(TopBorder).name());
1049     QString bottomBorderString = QString("%1pt %2 %3")
1050                                    .arg(QString::number(borderWidth(BottomBorder)),
1051                                         odfBorderStyleString(borderStyle(BottomBorder)),
1052                                         borderColor(BottomBorder).name());
1053 
1054     QString tlbrBorderString = QString("%1pt %2 %3")
1055                                 .arg(QString::number(borderWidth(TlbrBorder)),
1056                                      odfBorderStyleString(borderStyle(TlbrBorder)),
1057                                      borderColor(TlbrBorder).name());
1058     QString trblBorderString = QString("%1pt %2 %3")
1059                                    .arg(QString::number(borderWidth(BltrBorder)),
1060                                         odfBorderStyleString(borderStyle(BltrBorder)),
1061                                         borderColor(BltrBorder).name());
1062 
1063     // Get the strings that describe respective special borders (for special mso support).
1064     QString leftBorderSpecialString = msoBorderStyleString(borderStyle(LeftBorder));
1065     QString rightBorderSpecialString = msoBorderStyleString(borderStyle(RightBorder));
1066     QString topBorderSpecialString = msoBorderStyleString(borderStyle(TopBorder));
1067     QString bottomBorderSpecialString = msoBorderStyleString(borderStyle(BottomBorder));
1068     //QString tlbrBorderSpecialString = msoBorderStyleString(borderStyle(TlbrBorder));
1069     //QString trblBorderSpecialString = msoBorderStyleString(borderStyle(BltrBorder));
1070 
1071     // Check if we can save all borders in one fo:border attribute, or
1072     // if we have to use several different ones like fo:border-left, etc.
1073     if (leftBorderString == rightBorderString
1074         && leftBorderString == topBorderString
1075         && leftBorderString == bottomBorderString) {
1076 
1077         // Yes, they were all the same, so use only fo:border
1078         style.addProperty("fo:border", leftBorderString, type);
1079         style.addProperty("calligra:specialborder-left", leftBorderSpecialString, type);
1080         style.addProperty("calligra:specialborder-right", rightBorderSpecialString, type);
1081         style.addProperty("calligra:specialborder-top", topBorderSpecialString, type);
1082         style.addProperty("calligra:specialborder-bottom", bottomBorderSpecialString, type);
1083     } else {
1084         // No, they were different, so use the individual borders.
1085         //if (leftBorderStyle() != BorderNone)
1086             style.addProperty("fo:border-left", leftBorderString, type);
1087             style.addProperty("calligra:specialborder-left", leftBorderSpecialString, type);
1088         //if (rightBorderStyle() != BorderNone)
1089             style.addProperty("fo:border-right", rightBorderString, type);
1090             style.addProperty("calligra:specialborder-right", rightBorderSpecialString, type);
1091         //if (topBorderStyle() != BorderNone)
1092             style.addProperty("fo:border-top", topBorderString, type);
1093             style.addProperty("calligra:specialborder-top", topBorderSpecialString, type);
1094         //if (bottomBorderStyle() != BorderNone)
1095             style.addProperty("fo:border-bottom", bottomBorderString, type);
1096             style.addProperty("calligra:specialborder-bottom", bottomBorderSpecialString, type);
1097     }
1098 
1099     if (style.type() != KoGenStyle::PageLayoutStyle) {
1100         //if (tlbrBorderStyle() != BorderNone) {
1101             style.addProperty("style:diagonal-tl-br", tlbrBorderString, type);
1102         //}
1103         //if (trblBorderStyle() != BorderNone) {
1104             style.addProperty("style:diagonal-bl-tr", trblBorderString, type);
1105         //}
1106     }
1107 
1108     // Handle double borders
1109     QString leftBorderLineWidth = QString("%1pt %2pt %3pt")
1110                                     .arg(QString::number(innerBorderWidth(LeftBorder)),
1111                                          QString::number(borderSpacing(LeftBorder)),
1112                                          QString::number(outerBorderWidth(LeftBorder)));
1113     QString rightBorderLineWidth = QString("%1pt %2pt %3pt")
1114                                      .arg(QString::number(innerBorderWidth(RightBorder)),
1115                                           QString::number(borderSpacing(RightBorder)),
1116                                           QString::number(outerBorderWidth(RightBorder)));
1117     QString topBorderLineWidth = QString("%1pt %2pt %3pt")
1118                                    .arg(QString::number(innerBorderWidth(TopBorder)),
1119                                         QString::number(borderSpacing(TopBorder)),
1120                                         QString::number(outerBorderWidth(TopBorder)));
1121     QString bottomBorderLineWidth = QString("%1pt %2pt %3pt")
1122                                       .arg(QString::number(innerBorderWidth(BottomBorder)),
1123                                            QString::number(borderSpacing(BottomBorder)),
1124                                            QString::number(outerBorderWidth(BottomBorder)));
1125 
1126     QString tlbrBorderLineWidth = QString("%1pt %2pt %3pt")
1127                                    .arg(QString::number(innerBorderWidth(TlbrBorder)),
1128                                         QString::number(borderSpacing(TlbrBorder)),
1129                                         QString::number(outerBorderWidth(TlbrBorder)));
1130     QString trblBorderLineWidth = QString("%1pt %2pt %3pt")
1131                                       .arg(QString::number(innerBorderWidth(BltrBorder)),
1132                                            QString::number(borderSpacing(BltrBorder)),
1133                                            QString::number(outerBorderWidth(BltrBorder)));
1134 
1135     if (leftBorderLineWidth == rightBorderLineWidth
1136         && leftBorderLineWidth == topBorderLineWidth
1137         && leftBorderLineWidth == bottomBorderLineWidth
1138         && borderStyle(LeftBorder) == borderStyle(RightBorder)
1139         && borderStyle(TopBorder) == borderStyle(BottomBorder)
1140         && borderStyle(TopBorder) == borderStyle(LeftBorder)
1141         && (borderStyle(LeftBorder) == BorderDouble || borderStyle(LeftBorder) == BorderDoubleWave)) {
1142         style.addProperty("style:border-line-width", leftBorderLineWidth, type);
1143     } else {
1144         if (borderStyle(LeftBorder) == BorderDouble || borderStyle(LeftBorder) == BorderDoubleWave)
1145             style.addProperty("style:border-line-width-left", leftBorderLineWidth, type);
1146         if (borderStyle(RightBorder) == BorderDouble || borderStyle(RightBorder) == BorderDoubleWave)
1147             style.addProperty("style:border-line-width-right", rightBorderLineWidth, type);
1148         if (borderStyle(TopBorder) == BorderDouble || borderStyle(TopBorder) == BorderDoubleWave)
1149             style.addProperty("style:border-line-width-top", topBorderLineWidth, type);
1150         if (borderStyle(BottomBorder) == BorderDouble || borderStyle(BottomBorder) == BorderDoubleWave)
1151             style.addProperty("style:border-line-width-bottom", bottomBorderLineWidth, type);
1152     }
1153 
1154     if (style.type() != KoGenStyle::PageLayoutStyle) {
1155         if (borderStyle(TlbrBorder) == BorderDouble || borderStyle(TlbrBorder) == BorderDoubleWave) {
1156             style.addProperty("style:diagonal-tl-br-widths", tlbrBorderLineWidth, type);
1157         }
1158         if (borderStyle(BltrBorder) == BorderDouble || borderStyle(BltrBorder) == BorderDoubleWave) {
1159             style.addProperty("style:diagonal-bl-tr-widths", trblBorderLineWidth, type);
1160         }
1161     }
1162 }