[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [calligra] libs/kotext/styles: fix parsing of fo:border in KoParagraphStyle
From:       Friedrich W. H. Kossebau <kossebau () kde ! org>
Date:       2012-07-18 15:18:23
Message-ID: 20120718151823.1F919A6094 () git ! kde ! org
[Download RAW message or body]

Git commit 01115f4d747c98b01e69f24bb457ca2370d2b662 by Friedrich W. H. Kossebau.
Committed on 18/07/2012 at 17:10.
Pushed by kossebau into branch 'master'.

fix parsing of fo:border in KoParagraphStyle

Also changes a bad test value (was 0cm, while only positive integer are allowed for \
fo:border-line-width entries).

REVIEW: 105604

thanks boemann and thorsten for review

M  +132  -30   libs/kotext/styles/KoParagraphStyle.cpp
M  +2    -2    libs/kotext/styles/tests/TestOpenDocumentStyle.cpp

http://commits.kde.org/calligra/01115f4d747c98b01e69f24bb457ca2370d2b662

diff --git a/libs/kotext/styles/KoParagraphStyle.cpp \
b/libs/kotext/styles/KoParagraphStyle.cpp index 820da77..6a5b498 100644
--- a/libs/kotext/styles/KoParagraphStyle.cpp
+++ b/libs/kotext/styles/KoParagraphStyle.cpp
@@ -1265,6 +1265,82 @@ void KoParagraphStyle::loadOdf(const KoXmlElement *element, \
KoShapeLoadingContex  context.styleStack().restore();
 }
 
+struct ParagraphBorderData {
+    enum Values {Style = 1, Color = 2, Width = 4};
+
+    ParagraphBorderData()
+    : values(0) {}
+
+    ParagraphBorderData(const ParagraphBorderData &other)
+    : values(other.values), style(other.style), color(other.color), \
width(other.width) {} +
+    // flag defining which data is set
+    int values;
+
+    KoBorder::BorderStyle style;
+    QColor color;
+    qreal width; ///< in pt
+};
+
+
+/// Parses the @p dataString as value defined by CSS2  §7.29.3 "border"
+/// Adds parsed data to the data as set for @p defaultParagraphBorderData.
+/// Returns the enriched border data on success, the original @p \
defaultParagraphBorderData on a parsing error +static ParagraphBorderData \
parseParagraphBorderData(const QString &dataString, const ParagraphBorderData \
&defaultParagraphBorderData) +{
+    const QStringList bv = dataString.split(QLatin1Char(' '), \
QString::SkipEmptyParts); +    // too many items? ignore complete value
+    if (bv.count() > 3) {
+        return defaultParagraphBorderData;
+    }
+
+    ParagraphBorderData borderData = defaultParagraphBorderData;
+    int parsedValues = 0; ///< used to track what is read from the given string
+
+    foreach(const QString &v, bv) {
+        // try style
+        if (! (parsedValues & ParagraphBorderData::Style)) {
+            bool success = false;
+            KoBorder::BorderStyle style = KoBorder::odfBorderStyle(v, &success);
+            // workaround for not yet supported "hidden"
+            if (! success && (v == QLatin1String("hidden"))) {
+                // map to "none" for now TODO: KoBorder needs to support "hidden"
+                style = KoBorder::BorderNone;
+                success = true;
+            }
+            if (success) {
+                borderData.style = style;
+                borderData.values |= ParagraphBorderData::Style;
+                parsedValues |= ParagraphBorderData::Style;
+                continue;
+            }
+        }
+        // try color
+        if (! (parsedValues & ParagraphBorderData::Color)) {
+            const QColor color(v);
+            if (color.isValid()) {
+                borderData.color = color;
+                borderData.values |= ParagraphBorderData::Color;
+                parsedValues |= ParagraphBorderData::Color;
+                continue;
+            }
+        }
+        // try width
+        if (! (parsedValues & ParagraphBorderData::Width)) {
+            const qreal width = KoUnit::parseValue(v);
+            if (width >= 0.0) {
+                borderData.width = width;
+                borderData.values |= ParagraphBorderData::Width;
+                parsedValues |= ParagraphBorderData::Width;
+                continue;
+            }
+        }
+        // still here? found a value which cannot be parsed
+        return defaultParagraphBorderData;
+    }
+    return borderData;
+}
+
 void KoParagraphStyle::loadOdfProperties(KoShapeLoadingContext &scontext)
 {
     KoStyleStack &styleStack = scontext.odfLoadingContext().styleStack();
@@ -1541,59 +1617,85 @@ void \
KoParagraphStyle::loadOdfProperties(KoShapeLoadingContext &scontext)  #endif
 
     // Borders
-    const QString borderLeft(styleStack.property(KoXmlNS::fo, "border", "left"));
-    if (!borderLeft.isEmpty() && borderLeft != "none" && borderLeft != "hidden") {
-        QStringList bv = borderLeft.split(' ', QString::SkipEmptyParts);
-        setLeftBorderWidth(KoUnit::parseValue(bv.value(0), 1.0));
-        setLeftBorderStyle(KoBorder::odfBorderStyle(bv.value(1)));
-        setLeftBorderColor(QColor(bv.value(2)));
-        //setLeftInnerBorderWidth(qreal width);
-        //setLeftBorderSpacing(qreal width);
-    }
-    const QString borderTop(styleStack.property(KoXmlNS::fo, "border", "top"));
-    if (!borderTop.isEmpty() && borderTop != "none" && borderTop != "hidden") {
-        QStringList bv = borderTop.split(' ', QString::SkipEmptyParts);
-        setTopBorderWidth(KoUnit::parseValue(bv.value(0), 1.0));
-        setTopBorderStyle(KoBorder::odfBorderStyle(bv.value(1)));
-        setTopBorderColor(QColor(bv.value(2)));
-    }
-    const QString borderRight(styleStack.property(KoXmlNS::fo, "border", "right"));
-    if (!borderRight.isEmpty() && borderRight != "none" && borderRight != "hidden") \
                {
-        QStringList bv = borderRight.split(' ', QString::SkipEmptyParts);
-        setRightBorderWidth(KoUnit::parseValue(bv.value(0), 1.0));
-        setRightBorderStyle(KoBorder::odfBorderStyle(bv.value(1)));
-        setRightBorderColor(QColor(bv.value(2)));
-    }
-    const QString borderBottom(styleStack.property(KoXmlNS::fo, "border", \
                "bottom"));
-    if (!borderBottom.isEmpty() && borderBottom != "none" && borderBottom != \
                "hidden") {
-        QStringList bv = borderBottom.split(' ', QString::SkipEmptyParts);
-        setBottomBorderWidth(KoUnit::parseValue(bv.value(0), 1.0));
-        setBottomBorderStyle(KoBorder::odfBorderStyle(bv.value(1)));
-        setBottomBorderColor(QColor(bv.value(2)));
+    // The border attribute is actually three attributes in one string, all optional
+    // and with no given order. Also there is a hierachy, first the common for all
+    // sides and then overwrites per side, while in the code only the sides are \
stored. +    // So first the common data border is fetched, then this is overwritten \
per +    // side and the result stored.
+    const QString border(styleStack.property(KoXmlNS::fo, "border"));
+    const ParagraphBorderData borderData = parseParagraphBorderData(border, \
ParagraphBorderData()); +
+    const QString borderLeft(styleStack.property(KoXmlNS::fo, "border-left"));
+    const ParagraphBorderData leftParagraphBorderData = \
parseParagraphBorderData(borderLeft, borderData); +    if \
(leftParagraphBorderData.values & ParagraphBorderData::Width) { +        \
setLeftBorderWidth(leftParagraphBorderData.width); +    }
+    if (leftParagraphBorderData.values & ParagraphBorderData::Style) {
+        setLeftBorderStyle(leftParagraphBorderData.style);
+    }
+    if (leftParagraphBorderData.values & ParagraphBorderData::Color) {
+        setLeftBorderColor(leftParagraphBorderData.color);
+    }
+
+    const QString borderTop(styleStack.property(KoXmlNS::fo, "border-top"));
+    const ParagraphBorderData topParagraphBorderData = \
parseParagraphBorderData(borderTop, borderData); +    if \
(topParagraphBorderData.values & ParagraphBorderData::Width) { +        \
setTopBorderWidth(topParagraphBorderData.width); +    }
+    if (topParagraphBorderData.values & ParagraphBorderData::Style) {
+        setTopBorderStyle(topParagraphBorderData.style);
     }
+    if (topParagraphBorderData.values & ParagraphBorderData::Color) {
+        setTopBorderColor(topParagraphBorderData.color);
+    }
+
+    const QString borderRight(styleStack.property(KoXmlNS::fo, "border-right"));
+    const ParagraphBorderData rightParagraphBorderData = \
parseParagraphBorderData(borderRight, borderData); +    if \
(rightParagraphBorderData.values & ParagraphBorderData::Width) { +        \
setRightBorderWidth(rightParagraphBorderData.width); +    }
+    if (rightParagraphBorderData.values & ParagraphBorderData::Style) {
+        setRightBorderStyle(rightParagraphBorderData.style);
+    }
+    if (rightParagraphBorderData.values & ParagraphBorderData::Color) {
+        setRightBorderColor(rightParagraphBorderData.color);
+    }
+
+    const QString borderBottom(styleStack.property(KoXmlNS::fo, "border-bottom"));
+    const ParagraphBorderData bottomParagraphBorderData = \
parseParagraphBorderData(borderBottom, borderData); +    if \
(bottomParagraphBorderData.values & ParagraphBorderData::Width) { +        \
setBottomBorderWidth(bottomParagraphBorderData.width); +    }
+    if (bottomParagraphBorderData.values & ParagraphBorderData::Style) {
+        setBottomBorderStyle(bottomParagraphBorderData.style);
+    }
+    if (bottomParagraphBorderData.values & ParagraphBorderData::Color) {
+        setBottomBorderColor(bottomParagraphBorderData.color);
+    }
+
     const QString borderLineWidthLeft(styleStack.property(KoXmlNS::style, \
                "border-line-width", "left"));
-    if (!borderLineWidthLeft.isEmpty() && borderLineWidthLeft != "none" && \
borderLineWidthLeft != "hidden") { +    if (!borderLineWidthLeft.isEmpty()) {
         QStringList blw = borderLineWidthLeft.split(' ', QString::SkipEmptyParts);
         setLeftInnerBorderWidth(KoUnit::parseValue(blw.value(0), 0.1));
         setLeftBorderSpacing(KoUnit::parseValue(blw.value(1), 1.0));
         setLeftBorderWidth(KoUnit::parseValue(blw.value(2), 0.1));
     }
     const QString borderLineWidthTop(styleStack.property(KoXmlNS::style, \
                "border-line-width", "top"));
-    if (!borderLineWidthTop.isEmpty() && borderLineWidthTop != "none" && \
borderLineWidthTop != "hidden") { +    if (!borderLineWidthTop.isEmpty()) {
         QStringList blw = borderLineWidthTop.split(' ', QString::SkipEmptyParts);
         setTopInnerBorderWidth(KoUnit::parseValue(blw.value(0), 0.1));
         setTopBorderSpacing(KoUnit::parseValue(blw.value(1), 1.0));
         setTopBorderWidth(KoUnit::parseValue(blw.value(2), 0.1));
     }
     const QString borderLineWidthRight(styleStack.property(KoXmlNS::style, \
                "border-line-width", "right"));
-    if (!borderLineWidthRight.isEmpty() && borderLineWidthRight != "none" && \
borderLineWidthRight != "hidden") { +    if (!borderLineWidthRight.isEmpty()) {
         QStringList blw = borderLineWidthRight.split(' ', QString::SkipEmptyParts);
         setRightInnerBorderWidth(KoUnit::parseValue(blw.value(0), 0.1));
         setRightBorderSpacing(KoUnit::parseValue(blw.value(1), 1.0));
         setRightBorderWidth(KoUnit::parseValue(blw.value(2), 0.1));
     }
     const QString borderLineWidthBottom(styleStack.property(KoXmlNS::style, \
                "border-line-width", "bottom"));
-    if (!borderLineWidthBottom.isEmpty() && borderLineWidthBottom != "none" && \
borderLineWidthBottom != "hidden") { +    if (!borderLineWidthBottom.isEmpty()) {
         QStringList blw = borderLineWidthBottom.split(' ', QString::SkipEmptyParts);
         setBottomInnerBorderWidth(KoUnit::parseValue(blw.value(0), 0.1));
         setBottomBorderSpacing(KoUnit::parseValue(blw.value(1), 1.0));
diff --git a/libs/kotext/styles/tests/TestOpenDocumentStyle.cpp \
b/libs/kotext/styles/tests/TestOpenDocumentStyle.cpp index d0aadd4..d67bfc8 100644
--- a/libs/kotext/styles/tests/TestOpenDocumentStyle.cpp
+++ b/libs/kotext/styles/tests/TestOpenDocumentStyle.cpp
@@ -224,7 +224,7 @@ QStringList Attribute::listValuesFromNode(const QDomElement \
&m_node)  // This is not in the spec
             result << "100%" << "42%" << "-30%";
         } else if (reference == "borderWidths") {
-            result << "42px 42pt 12cm" << "2pt 23pt 0cm";
+            result << "42px 42pt 12cm" << "2pt 23pt 0.5cm";
         } else if (reference == "angle") {
             result << "5deg" << "1rad" << "400grad" << "3.14159265rad" << "45";    \
// OpenDocument 1.1 : no unit == degrees  } else if (reference == \
"zeroToHundredPercent") { @@ -681,7 +681,7 @@ void \
TestOpenDocumentStyle::testParagraphStyle_data()  QTest::addColumn<QString>("value");
     foreach (Attribute *attribute, attributes) {
         foreach (QString value, attribute->listValues()) {
-            QTest::newRow(attribute->name().toLatin1()) << attribute << value;
+            QTest::newRow((attribute->name()+QLatin1Char('/')+value).toLatin1()) << \
attribute << value;  }
     }
 }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic