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