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