KoParagraphStyle.cpp 83.4 KB
Newer Older
Thomas Zander's avatar
Thomas Zander committed
1
/* This file is part of the KDE project
2
 * Copyright (C) 2006-2009 Thomas Zander <zander@kde.org>
Sebastian Sauer's avatar
Sebastian Sauer committed
3
 * Copyright (C) 2007,2008 Sebastian Sauer <mail@dipe.org>
4
 * Copyright (C) 2007-2011 Pierre Ducroquet <pinaraf@pinaraf.info>
5
 * Copyright (C) 2008 Thorsten Zachmann <zachmann@kde.org>
6
 * Copyright (C) 2008 Roopesh Chander <roop@forwardbias.in>
7
 * Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in>
8
 * Copyright (C) 2011 Gopalakrishna Bhat A <gopalakbhat@gmail.com>
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
Thomas Zander's avatar
Thomas Zander committed
25
#include "KoParagraphStyle.h"
26
#include "KoCharacterStyle.h"
27
#include "KoListStyle.h"
Thomas Zander's avatar
Thomas Zander committed
28
#include "KoTextBlockData.h"
29
#include "KoStyleManager.h"
30
#include "KoListLevelProperties.h"
31 32
#include "KoTextSharedLoadingData.h"
#include <KoShapeLoadingContext.h>
33
#include <KoShapeSavingContext.h>
34 35
#include <KoGenStyle.h>
#include <KoGenStyles.h>
Thomas Zander's avatar
Thomas Zander committed
36
#include "Styles_p.h"
37
#include "KoTextDocument.h"
Thomas Zander's avatar
Thomas Zander committed
38

39 40
#include <KDebug>

41 42 43
#include <QTextBlock>
#include <QTextBlockFormat>
#include <QTextCursor>
44
#include <QFontMetrics>
45
#include <QBuffer>
46

47 48
#include <KoUnit.h>
#include <KoStyleStack.h>
49
#include <KoOdfLoadingContext.h>
50
#include <KoXmlNS.h>
51
#include <KoXmlWriter.h>
52
#include <KoBorder.h>
53

Laurent Montel's avatar
Laurent Montel committed
54 55
//already defined in KoRulerController.cpp
#ifndef KDE_USE_FINAL
56 57
static int compareTabs(KoText::Tab &tab1, KoText::Tab &tab2)
{
58 59
    return tab1.position < tab2.position;
}
Laurent Montel's avatar
Laurent Montel committed
60
#endif
61 62
class KoParagraphStyle::Private
{
63
public:
64
    Private() : parentStyle(0), defaultStyle(0), list(0) {}
65

66 67
    ~Private()
    {
68 69
    }

70 71
    void setProperty(int key, const QVariant &value)
    {
72
        stylesPrivate.add(key, value);
73 74
    }

75 76 77 78 79 80 81 82 83 84 85 86 87 88
    void ensureDefaults(QTextBlockFormat &format)
    {
        if (defaultStyle) {
            QMap<int, QVariant> props = defaultStyle->d->stylesPrivate.properties();
            QMap<int, QVariant>::const_iterator it = props.constBegin();
            while (it != props.constEnd()) {
                if (!it.value().isNull() && !format.hasProperty(it.key())) {
                    format.setProperty(it.key(), it.value());
                }
                ++it;
            }
        }
    }

89
    QString name;
90
    KoParagraphStyle *parentStyle;
91
    KoParagraphStyle *defaultStyle;
92
    KoList *list;
93
    StylePrivate stylesPrivate;
94
};
95

96
KoParagraphStyle::KoParagraphStyle(QObject *parent)
97
        : KoCharacterStyle(parent), d(new Private())
Thomas Zander's avatar
Thomas Zander committed
98
{
99 100
}

101
KoParagraphStyle::KoParagraphStyle(const QTextBlockFormat &blockFormat, const QTextCharFormat &blockCharFormat, QObject *parent)
102
        : KoCharacterStyle(blockCharFormat, parent),
103
        d(new Private())
104
{
105
    d->stylesPrivate = blockFormat.properties();
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
}

KoParagraphStyle *KoParagraphStyle::fromBlock(const QTextBlock &block, QObject *parent)
{
    QTextBlockFormat blockFormat = block.blockFormat();
    QTextCursor cursor(block);
    KoParagraphStyle *answer = new KoParagraphStyle(blockFormat, cursor.blockCharFormat(), parent);

    int listStyleId = blockFormat.intProperty(ListStyleId);
    KoStyleManager *sm = KoTextDocument(block.document()).styleManager();
    if (KoListStyle *listStyle = sm->listStyle(listStyleId)) {
        answer->setListStyle(listStyle->clone(answer));
    } else if (block.textList()) {
        KoListLevelProperties llp = KoListLevelProperties::fromTextList(block.textList());
        KoListStyle *listStyle = new KoListStyle(answer);
        listStyle->setLevelProperties(llp);
        answer->setListStyle(listStyle);
    }
    return answer;
125 126
}

127 128
KoParagraphStyle::~KoParagraphStyle()
{
129
    delete d;
Thomas Zander's avatar
Thomas Zander committed
130 131
}

132 133 134 135 136 137
void KoParagraphStyle::setDefaultStyle(KoParagraphStyle *defaultStyle)
{
    d->defaultStyle = defaultStyle;
    KoCharacterStyle::setDefaultStyle(defaultStyle);
}

138
void KoParagraphStyle::setParentStyle(KoParagraphStyle *parent)
139
{
140
    d->parentStyle = parent;
141
    KoCharacterStyle::setParentStyle(parent);
Thomas Zander's avatar
Thomas Zander committed
142 143
}

144 145
void KoParagraphStyle::setProperty(int key, const QVariant &value)
{
146 147
    if (d->parentStyle) {
        QVariant var = d->parentStyle->value(key);
148
        if (!var.isNull() && var == value) { // same as parent, so its actually a reset.
149
            d->stylesPrivate.remove(key);
Thomas Zander's avatar
Thomas Zander committed
150 151 152
            return;
        }
    }
153
    d->stylesPrivate.add(key, value);
Thomas Zander's avatar
Thomas Zander committed
154 155
}

156 157
void KoParagraphStyle::remove(int key)
{
158
    d->stylesPrivate.remove(key);
159 160
}

161 162
QVariant KoParagraphStyle::value(int key) const
{
163
    QVariant var = d->stylesPrivate.value(key);
164 165 166 167 168 169
    if (var.isNull()) {
        if (d->parentStyle)
            return d->parentStyle->value(key);
        else if (d->defaultStyle)
            return d->defaultStyle->value(key);
    }
Thomas Zander's avatar
Thomas Zander committed
170 171 172
    return var;
}

173 174
bool KoParagraphStyle::hasProperty(int key) const
{
175
    return d->stylesPrivate.contains(key);
176 177
}

178 179
qreal KoParagraphStyle::propertyDouble(int key) const
{
180
    QVariant variant = value(key);
181
    if (variant.isNull())
Thomas Zander's avatar
Thomas Zander committed
182
        return 0.0;
183
    return variant.toDouble();
Thomas Zander's avatar
Thomas Zander committed
184 185
}

186 187 188 189 190 191 192
QTextLength KoParagraphStyle::propertyLength(int key) const
{
    QVariant variant = value(key);
    if (variant.isNull())
        return QTextLength(QTextLength::FixedLength, 0.0);
    if (!variant.canConvert<QTextLength>())
    {
193 194 195 196 197
        // Fake support, for compatibility sake
        if (variant.canConvert<qreal>())
        {
            return QTextLength(QTextLength::FixedLength, variant.toReal());
        }
198

199 200 201 202 203 204
        kWarning(32500) << "This should never happen : requested property can't be converted to QTextLength";
        return QTextLength(QTextLength::FixedLength, 0.0);
    }
    return variant.value<QTextLength>();
}

205 206
int KoParagraphStyle::propertyInt(int key) const
{
207
    QVariant variant = value(key);
208
    if (variant.isNull())
Thomas Zander's avatar
Thomas Zander committed
209
        return 0;
210
    return variant.toInt();
Thomas Zander's avatar
Thomas Zander committed
211 212
}

213 214
bool KoParagraphStyle::propertyBoolean(int key) const
{
215
    QVariant variant = value(key);
216
    if (variant.isNull())
217
        return false;
218
    return variant.toBool();
219 220
}

221 222
QColor KoParagraphStyle::propertyColor(int key) const
{
223
    QVariant variant = value(key);
224
    if (variant.isNull()) {
Jarosław Staniek's avatar
 
Jarosław Staniek committed
225
        return QColor();
226
    }
227
    return qvariant_cast<QColor>(variant);
228 229
}

230
void KoParagraphStyle::applyStyle(QTextBlockFormat &format) const
231
{
232 233
    bool hadBreakBefore = format.hasProperty(BreakBefore);
    bool hadBreakAfter = format.hasProperty(BreakAfter);
234

235 236
    if (d->parentStyle) {
        d->parentStyle->applyStyle(format);
237
    }
238

239 240 241 242 243 244 245 246 247
    if (!hadBreakBefore) {
         // page preak should not be inherited according to odf, yet if it was there
         // before we shouldn't remove
         format.clearProperty(BreakBefore);
    }
    if (!hadBreakAfter) {
         // page preak should not be inherited according to odf, yet if it was there
         // before we shouldn't remove
         format.clearProperty(BreakAfter);
248
    }
249 250 251
    const QMap<int, QVariant> props = d->stylesPrivate.properties();
    QMap<int, QVariant>::const_iterator it = props.begin();
    while (it != props.end()) {
252 253 254 255 256 257 258 259 260
        if (it.key() == QTextBlockFormat::BlockLeftMargin) {
            format.setLeftMargin(leftMargin());
        } else if (it.key() == QTextBlockFormat::BlockRightMargin) {
            format.setRightMargin(rightMargin());
        } else if (it.key() == QTextBlockFormat::TextIndent) {
            format.setTextIndent(textIndent());
        } else {
            format.setProperty(it.key(), it.value());
        }
261
        ++it;
262
    }
263 264 265
    if ((hasProperty(DefaultOutlineLevel)) && (!format.hasProperty(OutlineLevel))) {
       format.setProperty(OutlineLevel, defaultOutlineLevel());
    }
266 267
}

268 269
void KoParagraphStyle::applyStyle(QTextBlock &block, bool applyListStyle) const
{
270 271 272
    QTextCursor cursor(block);
    QTextBlockFormat format = cursor.blockFormat();
    applyStyle(format);
273
    d->ensureDefaults(format);
274
    cursor.setBlockFormat(format);
275 276

    KoCharacterStyle::applyStyle(block);
277

278
    if (applyListStyle) {
279 280 281
        applyParagraphListStyle(block, format);
    }
}
282

283 284 285 286 287 288 289 290 291 292 293 294
void KoParagraphStyle::applyParagraphListStyle(QTextBlock &block, const QTextBlockFormat &blockFormat) const
{
    //gopalakbhat: We need to differentiate between normal styles and styles with outline(part of heading)
    //Styles part of outline: We ignore the listStyle()( even if this is a valid in ODF; even LibreOffice does the same)
    //                        since we can specify all info required in text:outline-style
    //Normal styles: we use the listStyle()
    if (blockFormat.hasProperty(OutlineLevel)) {
        if (! d->list) {
            if (! KoTextDocument(block.document()).headingList()) {
                if (KoTextDocument(block.document()).styleManager() && KoTextDocument(block.document()).styleManager()->outlineStyle()) {
                    d->list = new KoList(block.document(), KoTextDocument(block.document()).styleManager()->outlineStyle());
                    KoTextDocument(block.document()).setHeadingList(d->list);
295 296
                }
            } else {
297 298 299 300 301 302 303 304 305 306
                d->list = KoTextDocument(block.document()).headingList();
            }
        }
        if (d->list) {
            d->list->applyStyle(block, KoTextDocument(block.document()).styleManager()->outlineStyle(), blockFormat.intProperty(OutlineLevel));
        }
    } else {
        if (listStyle()) {
            if (!d->list) {
                d->list = new KoList(block.document(), listStyle());
307
            }
308 309 310 311 312 313 314 315 316 317 318 319
            //FIXME: Gopalakrishna Bhat A: This condition should never happen.
            // i.e. d->list->style() should always be in sync with the listStyle()
            if (d->list->style() != listStyle()) {
                d->list->setStyle(listStyle());
            }
            d->list->add(block, listLevel());
        } else {
            if (block.textList())
                block.textList()->remove(block);
            KoTextBlockData *data = dynamic_cast<KoTextBlockData*>(block.userData());
            if (data)
                data->setCounterWidth(-1);
320
        }
321 322 323
    }
}

324 325 326 327 328 329 330 331 332 333 334
void KoParagraphStyle::unapplyStyle(QTextBlock &block) const
{
    if (d->parentStyle)
        d->parentStyle->unapplyStyle(block);

    QTextCursor cursor(block);
    QTextBlockFormat format = cursor.blockFormat();

    QList<int> keys = d->stylesPrivate.keys();
    for (int i = 0; i < keys.count(); i++) {
        QVariant variant = d->stylesPrivate.value(keys[i]);
335 336 337 338 339 340 341 342 343 344 345 346 347
        if (keys[i] == QTextBlockFormat::BlockLeftMargin) {
            if (leftMargin() == format.property(keys[i]))
                format.clearProperty(keys[i]);
        } else if (keys[i] == QTextBlockFormat::BlockRightMargin) {
            if (rightMargin() == format.property(keys[i]))
                format.clearProperty(keys[i]);
        } else if (keys[i] == QTextBlockFormat::TextIndent) {
            if (textIndent() == format.property(keys[i]))
                format.clearProperty(keys[i]);
        } else {
            if (variant == format.property(keys[i]))
                format.clearProperty(keys[i]);
        }
348
    }
349 350 351

    format.clearProperty(KoParagraphStyle::OutlineLevel);

352
    cursor.setBlockFormat(format);
353
    KoCharacterStyle::unapplyStyle(block);
354 355 356 357 358 359 360
    if (listStyle() && block.textList()) { // TODO check its the same one?
        KoList::remove(block);
    }
    if (d->list && block.textList()) { // TODO check its the same one?
        KoList::remove(block);
    }

361 362
}

363
void KoParagraphStyle::setLineHeightPercent(qreal lineHeight)
364
{
365
    setProperty(PercentLineHeight, lineHeight);
366
    setProperty(FixedLineHeight, 0.0);
367
    setProperty(MinimumLineHeight, QTextLength(QTextLength::FixedLength, 0.0));
368
    remove(NormalLineHeight);
369 370
}

371
qreal KoParagraphStyle::lineHeightPercent() const
372
{
373 374 375
    return propertyInt(PercentLineHeight);
}

376 377
void KoParagraphStyle::setLineHeightAbsolute(qreal height)
{
378
    setProperty(FixedLineHeight, height);
Sebastian Sauer's avatar
Sebastian Sauer committed
379
    setProperty(PercentLineHeight, 0);
380
    setProperty(MinimumLineHeight, QTextLength(QTextLength::FixedLength, 0.0));
381
    remove(NormalLineHeight);
382 383
}

384 385
qreal KoParagraphStyle::lineHeightAbsolute() const
{
386 387 388
    return propertyDouble(FixedLineHeight);
}

389
void KoParagraphStyle::setMinimumLineHeight(const QTextLength &height)
390
{
391 392
    setProperty(FixedLineHeight, 0.0);
    setProperty(PercentLineHeight, 0);
393
    setProperty(MinimumLineHeight, height);
394
    remove(NormalLineHeight);
395 396
}

397 398
qreal KoParagraphStyle::minimumLineHeight() const
{
399 400 401 402
    if (parentStyle())
        return propertyLength(MinimumLineHeight).value(parentStyle()->minimumLineHeight());
    else
        return propertyLength(MinimumLineHeight).value(0);
403 404
}

405 406
void KoParagraphStyle::setLineSpacing(qreal spacing)
{
407
    setProperty(LineSpacing, spacing);
408
    remove(NormalLineHeight);
409 410
}

411 412
qreal KoParagraphStyle::lineSpacing() const
{
413 414 415
    return propertyDouble(LineSpacing);
}

416 417
void KoParagraphStyle::setLineSpacingFromFont(bool on)
{
418
    setProperty(LineSpacingFromFont, on);
419
    remove(NormalLineHeight);
420 421
}

422 423
bool KoParagraphStyle::lineSpacingFromFont() const
{
424 425 426
    return propertyBoolean(LineSpacingFromFont);
}

427 428 429 430 431
void KoParagraphStyle::setNormalLineHeight()
{
    setProperty(NormalLineHeight, true);
    setProperty(PercentLineHeight, 0);
    setProperty(FixedLineHeight, 0.0);
432
    setProperty(MinimumLineHeight, QTextLength(QTextLength::FixedLength, 0.0));
433 434 435 436 437 438 439 440
    setProperty(LineSpacing, 0.0);
}

bool KoParagraphStyle::hasNormalLineHeight() const
{
    return propertyBoolean(NormalLineHeight);
}

441 442
void KoParagraphStyle::setAlignLastLine(Qt::Alignment alignment)
{
443 444 445
    setProperty(AlignLastLine, (int) alignment);
}

446 447
Qt::Alignment KoParagraphStyle::alignLastLine() const
{
448 449 450 451
    if (hasProperty(AlignLastLine))
        return static_cast<Qt::Alignment>(propertyInt(AlignLastLine));
    // Hum, that doesn't sound right !
    return alignment();
452 453
}

454 455
void KoParagraphStyle::setWidowThreshold(int lines)
{
456 457 458
    setProperty(WidowThreshold, lines);
}

459 460
int KoParagraphStyle::widowThreshold() const
{
461 462 463
    return propertyInt(WidowThreshold);
}

464 465
void KoParagraphStyle::setOrphanThreshold(int lines)
{
466 467 468
    setProperty(OrphanThreshold, lines);
}

469 470
int KoParagraphStyle::orphanThreshold() const
{
471 472 473
    return propertyInt(OrphanThreshold);
}

474 475
void KoParagraphStyle::setDropCaps(bool on)
{
476 477 478
    setProperty(DropCaps, on);
}

479 480
bool KoParagraphStyle::dropCaps() const
{
481 482 483
    return propertyBoolean(DropCaps);
}

484 485
void KoParagraphStyle::setDropCapsLength(int characters)
{
486 487 488
    setProperty(DropCapsLength, characters);
}

489 490
int KoParagraphStyle::dropCapsLength() const
{
491 492 493
    return propertyInt(DropCapsLength);
}

494 495
void KoParagraphStyle::setDropCapsLines(int lines)
{
496 497 498
    setProperty(DropCapsLines, lines);
}

499 500
int KoParagraphStyle::dropCapsLines() const
{
501 502 503
    return propertyInt(DropCapsLines);
}

504 505
void KoParagraphStyle::setDropCapsDistance(qreal distance)
{
506 507 508
    setProperty(DropCapsDistance, distance);
}

509 510
qreal KoParagraphStyle::dropCapsDistance() const
{
511 512 513
    return propertyDouble(DropCapsDistance);
}

514 515 516 517 518 519 520 521 522 523
void KoParagraphStyle::setDropCapsTextStyleId(int id)
{
    setProperty(KoParagraphStyle::DropCapsTextStyle, id);
}

int KoParagraphStyle::dropCapsTextStyleId() const
{
    return propertyInt(KoParagraphStyle::DropCapsTextStyle);
}

524 525
void KoParagraphStyle::setFollowDocBaseline(bool on)
{
526 527 528
    setProperty(FollowDocBaseline, on);
}

529 530
bool KoParagraphStyle::followDocBaseline() const
{
531 532 533
    return propertyBoolean(FollowDocBaseline);
}

534
void KoParagraphStyle::setBreakBefore(KoText::KoTextBreakProperty value)
535
{
536
    setProperty(BreakBefore, value);
537 538
}

539
KoText::KoTextBreakProperty KoParagraphStyle::breakBefore() const
540
{
541
    return static_cast<KoText::KoTextBreakProperty>(propertyInt(BreakBefore));
542 543
}

544
void KoParagraphStyle::setBreakAfter(KoText::KoTextBreakProperty value)
545
{
546
    setProperty(BreakAfter, value);
547 548
}

549
KoText::KoTextBreakProperty KoParagraphStyle::breakAfter() const
550
{
551
    return static_cast<KoText::KoTextBreakProperty>(propertyInt(BreakAfter));
552 553
}

554 555
void KoParagraphStyle::setLeftPadding(qreal padding)
{
556 557 558
    setProperty(LeftPadding, padding);
}

559
qreal KoParagraphStyle::leftPadding() const
560
{
561 562 563
    return propertyDouble(LeftPadding);
}

564 565
void KoParagraphStyle::setTopPadding(qreal padding)
{
566 567 568
    setProperty(TopPadding, padding);
}

569
qreal KoParagraphStyle::topPadding() const
570
{
571 572 573
    return propertyDouble(TopPadding);
}

574 575
void KoParagraphStyle::setRightPadding(qreal padding)
{
576 577 578
    setProperty(RightPadding, padding);
}

579
qreal KoParagraphStyle::rightPadding() const
580
{
581 582 583
    return propertyDouble(RightPadding);
}

584 585
void KoParagraphStyle::setBottomPadding(qreal padding)
{
586 587 588
    setProperty(BottomPadding, padding);
}

589
qreal KoParagraphStyle::bottomPadding() const
590
{
591 592 593
    return propertyDouble(BottomPadding);
}

594 595
void KoParagraphStyle::setPadding(qreal padding)
{
596 597 598 599 600 601
    setBottomPadding(padding);
    setTopPadding(padding);
    setRightPadding(padding);
    setLeftPadding(padding);
}

602 603
void KoParagraphStyle::setLeftBorderWidth(qreal width)
{
604 605 606
    setProperty(LeftBorderWidth, width);
}

607
qreal KoParagraphStyle::leftBorderWidth() const
608
{
609 610 611
    return propertyDouble(LeftBorderWidth);
}

612 613
void KoParagraphStyle::setLeftInnerBorderWidth(qreal width)
{
614 615 616
    setProperty(LeftInnerBorderWidth, width);
}

617
qreal KoParagraphStyle::leftInnerBorderWidth() const
618
{
619 620 621
    return propertyDouble(LeftInnerBorderWidth);
}

622 623
void KoParagraphStyle::setLeftBorderSpacing(qreal width)
{
624 625 626
    setProperty(LeftBorderSpacing, width);
}

627
qreal KoParagraphStyle::leftBorderSpacing() const
628
{
629 630 631
    return propertyDouble(LeftBorderSpacing);
}

632
void KoParagraphStyle::setLeftBorderStyle(KoBorder::BorderStyle style)
633
{
634 635 636
    setProperty(LeftBorderStyle, style);
}

637
KoBorder::BorderStyle KoParagraphStyle::leftBorderStyle() const
638
{
639
    return static_cast<KoBorder::BorderStyle>(propertyInt(LeftBorderStyle));
640 641
}

642
void KoParagraphStyle::setLeftBorderColor(const QColor &color)
643
{
644 645 646
    setProperty(LeftBorderColor, color);
}

647
QColor KoParagraphStyle::leftBorderColor() const
648
{
649 650 651
    return propertyColor(LeftBorderColor);
}

652 653
void KoParagraphStyle::setTopBorderWidth(qreal width)
{
654 655 656
    setProperty(TopBorderWidth, width);
}

657
qreal KoParagraphStyle::topBorderWidth() const
658
{
659 660 661
    return propertyDouble(TopBorderWidth);
}

662 663
void KoParagraphStyle::setTopInnerBorderWidth(qreal width)
{
664 665 666
    setProperty(TopInnerBorderWidth, width);
}

667
qreal KoParagraphStyle::topInnerBorderWidth() const
668
{
669 670 671
    return propertyDouble(TopInnerBorderWidth);
}

672 673
void KoParagraphStyle::setTopBorderSpacing(qreal width)
{
674 675 676
    setProperty(TopBorderSpacing, width);
}

677
qreal KoParagraphStyle::topBorderSpacing() const
678
{
679 680 681
    return propertyDouble(TopBorderSpacing);
}

682
void KoParagraphStyle::setTopBorderStyle(KoBorder::BorderStyle style)
683
{
684 685 686
    setProperty(TopBorderStyle, style);
}

687
KoBorder::BorderStyle KoParagraphStyle::topBorderStyle() const
688
{
689
    return static_cast<KoBorder::BorderStyle>(propertyInt(TopBorderStyle));
690 691
}

692
void KoParagraphStyle::setTopBorderColor(const QColor &color)
693
{
694 695 696
    setProperty(TopBorderColor, color);
}

697
QColor KoParagraphStyle::topBorderColor() const
698
{
699 700 701
    return propertyColor(TopBorderColor);
}

702 703
void KoParagraphStyle::setRightBorderWidth(qreal width)
{
704 705 706
    setProperty(RightBorderWidth, width);
}

707
qreal KoParagraphStyle::rightBorderWidth() const
708
{
709 710 711
    return propertyDouble(RightBorderWidth);
}

712 713
void KoParagraphStyle::setRightInnerBorderWidth(qreal width)
{
714 715 716
    setProperty(RightInnerBorderWidth, width);
}

717
qreal KoParagraphStyle::rightInnerBorderWidth() const
718
{
719 720 721
    return propertyDouble(RightInnerBorderWidth);
}

722 723
void KoParagraphStyle::setRightBorderSpacing(qreal width)
{
724 725 726
    setProperty(RightBorderSpacing, width);
}

727
qreal KoParagraphStyle::rightBorderSpacing() const
728
{
729 730 731
    return propertyDouble(RightBorderSpacing);
}

732
void KoParagraphStyle::setRightBorderStyle(KoBorder::BorderStyle style)
733
{
734 735 736
    setProperty(RightBorderStyle, style);
}

737
KoBorder::BorderStyle KoParagraphStyle::rightBorderStyle() const
738
{
739
    return static_cast<KoBorder::BorderStyle>(propertyInt(RightBorderStyle));
740 741
}

742
void KoParagraphStyle::setRightBorderColor(const QColor &color)
743
{
744 745 746
    setProperty(RightBorderColor, color);
}

747
QColor KoParagraphStyle::rightBorderColor() const
748
{
749 750 751
    return propertyColor(RightBorderColor);
}

752 753
void KoParagraphStyle::setBottomBorderWidth(qreal width)
{
754 755 756
    setProperty(BottomBorderWidth, width);
}

757
qreal KoParagraphStyle::bottomBorderWidth() const
758
{
759 760 761
    return propertyDouble(BottomBorderWidth);
}

762 763
void KoParagraphStyle::setBottomInnerBorderWidth(qreal width)
{
764 765 766
    setProperty(BottomInnerBorderWidth, width);
}

767
qreal KoParagraphStyle::bottomInnerBorderWidth() const
768
{
769 770 771
    return propertyDouble(BottomInnerBorderWidth);
}

772 773
void KoParagraphStyle::setBottomBorderSpacing(qreal width)
{
774 775 776
    setProperty(BottomBorderSpacing, width);
}

777
qreal KoParagraphStyle::bottomBorderSpacing() const
778
{
779 780 781
    return propertyDouble(BottomBorderSpacing);
}

782
void KoParagraphStyle::setBottomBorderStyle(KoBorder::BorderStyle style)
783
{
784 785 786
    setProperty(BottomBorderStyle, style);
}

787
KoBorder::BorderStyle KoParagraphStyle::bottomBorderStyle() const
788
{
789
    return static_cast<KoBorder::BorderStyle>(propertyInt(BottomBorderStyle));
790 791
}

792
void KoParagraphStyle::setBottomBorderColor(const QColor &color)
793
{
794 795 796
    setProperty(BottomBorderColor, color);
}

797
QColor KoParagraphStyle::bottomBorderColor() const
798
{
799 800 801
    return propertyColor(BottomBorderColor);
}

802
void KoParagraphStyle::setTopMargin(QTextLength topMargin)
803
{
804 805 806
    setProperty(QTextFormat::BlockTopMargin, topMargin);
}

807
qreal KoParagraphStyle::topMargin() const
808
{
809 810 811 812
    if (parentStyle())
        return propertyLength(QTextFormat::BlockTopMargin).value(parentStyle()->topMargin());
    else
        return propertyLength(QTextFormat::BlockTopMargin).value(0);
813 814
}

815
void KoParagraphStyle::setBottomMargin(QTextLength margin)
816
{
817 818 819
    setProperty(QTextFormat::BlockBottomMargin, margin);
}

820
qreal KoParagraphStyle::bottomMargin() const
821
{
822
    if (parentStyle())
823
        return propertyLength(QTextFormat::BlockBottomMargin).value(parentStyle()->bottomMargin());
824 825
    else
        return propertyLength(QTextFormat::BlockBottomMargin).value(0);
826 827
}

828
void KoParagraphStyle::setLeftMargin(QTextLength margin)