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

List:       kde-commits
Subject:    [calligra] sheets: more work on odf code separation
From:       Tomas Mecir <mecirt () gmail ! com>
Date:       2016-03-06 17:21:11
Message-ID: E1accMh-0005vS-9K () scm ! kde ! org
[Download RAW message or body]

Git commit 0356edee381f36b301d0774f40cbc3cccfb7c03f by Tomas Mecir.
Committed on 24/01/2016 at 23:33.
Pushed by mecir into branch 'master'.

more work on odf code separation

M  +1    -0    sheets/CMakeLists.txt
M  +0    -887  sheets/Cell.cpp
M  +0    -54   sheets/Cell.h
M  +89   -14   sheets/Style.cpp
M  +0    -74   sheets/Util.cpp
M  +0    -14   sheets/Util.h
M  +934  -0    sheets/odf/SheetsOdfCell.cpp
M  +18   -7    sheets/odf/SheetsOdfSheet.cpp

http://commits.kde.org/calligra/0356edee381f36b301d0774f40cbc3cccfb7c03f

diff --git a/sheets/CMakeLists.txt b/sheets/CMakeLists.txt
index b6c6a25..7b75778 100644
--- a/sheets/CMakeLists.txt
+++ b/sheets/CMakeLists.txt
@@ -150,6 +150,7 @@ set (odf_DIR_SRCS
     odf/SheetsOdfMap.cpp
     odf/SheetsOdfSheet.cpp
     odf/SheetsOdfCell.cpp
+    odf/SheetsOdfStyle.cpp
     )
 
 set (part_DIR_SRCS
diff --git a/sheets/Cell.cpp b/sheets/Cell.cpp
index 3ded273..92f8377 100644
--- a/sheets/Cell.cpp
+++ b/sheets/Cell.cpp
@@ -52,17 +52,13 @@
 #include "CellStorage.h"
 #include "Condition.h"
 #include "Formula.h"
-#include "GenValidationStyle.h"
 #include "Global.h"
 #include "Localization.h"
 #include "LoadingInfo.h"
 #include "Map.h"
 #include "NamedAreaManager.h"
-#include "OdfLoadingContext.h"
-#include "OdfSavingContext.h"
 #include "RowColumnFormat.h"
 #include "RowFormatStorage.h"
-#include "ShapeApplicationData.h"
 #include "Sheet.h"
 #include "Style.h"
 #include "StyleManager.h"
@@ -74,19 +70,8 @@
 #include "ValueParser.h"
 #include "StyleStorage.h"
 
-#include <KoUnit.h>
-#include <KoShape.h>
-#include <KoShapeLoadingContext.h>
-#include <KoShapeRegistry.h>
-#include <KoXmlNS.h>
 #include <KoXmlReader.h>
-#include <KoXmlWriter.h>
 
-#include <KoTextLoader.h>
-#include <KoStyleManager.h>
-#include <KoTextSharedLoadingData.h>
-#include <KoTextDocument.h>
-#include <KoTextWriter.h>
 #include <KoParagraphStyle.h>
 
 #include <QTimer>
@@ -1069,878 +1054,6 @@ bool Cell::saveCellResult(QDomDocument& doc, QDomElement& \
                result,
     return true; /* really isn't much of a way for this function to fail */
 }
 
-void Cell::saveOdfAnnotation(KoXmlWriter &xmlwriter)
-{
-    const QString comment = this->comment();
-    if (!comment.isEmpty()) {
-        //<office:annotation draw:style-name="gr1" draw:text-style-name="P1" \
svg:width="2.899cm" svg:height="2.691cm" svg:x="2.858cm" svg:y="0.001cm" \
                draw:caption-point-x="-2.858cm" draw:caption-point-y="-0.001cm">
-        xmlwriter.startElement("office:annotation");
-        const QStringList text = comment.split('\n', QString::SkipEmptyParts);
-        for (QStringList::ConstIterator it = text.begin(); it != text.end(); ++it) {
-            xmlwriter.startElement("text:p");
-            xmlwriter.addTextNode(*it);
-            xmlwriter.endElement();
-        }
-        xmlwriter.endElement();
-    }
-}
-
-QString Cell::saveOdfCellStyle(KoGenStyle &currentCellStyle, KoGenStyles \
                &mainStyles)
-{
-    const Conditions conditions = this->conditions();
-    if (!conditions.isEmpty()) {
-        // this has to be an automatic style
-        currentCellStyle = KoGenStyle(KoGenStyle::TableCellAutoStyle, "table-cell");
-        conditions.saveOdfConditions(currentCellStyle, sheet()->map()->converter());
-    }
-    return style().saveOdf(currentCellStyle, mainStyles, \
                d->sheet->map()->styleManager());
-}
-
-
-bool Cell::saveOdf(int row, int column, int &repeated,
-                   OdfSavingContext& tableContext)
-{
-    KoXmlWriter & xmlwriter = tableContext.shapeContext.xmlWriter();
-    KoGenStyles & mainStyles = tableContext.shapeContext.mainStyles();
-
-    // see: OpenDocument, 8.1.3 Table Cell
-    if (!isPartOfMerged())
-        xmlwriter.startElement("table:table-cell");
-    else
-        xmlwriter.startElement("table:covered-table-cell");
-#if 0
-    //add font style
-    QFont font;
-    Value const value(cell.value());
-    if (!cell.isDefault()) {
-        font = cell.format()->textFont(i, row);
-        m_styles.addFont(font);
-
-        if (cell.format()->hasProperty(Style::SComment))
-            hasComment = true;
-    }
-#endif
-    // NOTE save the value before the style as long as the Formatter does not work \
                correctly
-    if (link().isEmpty())
-        saveOdfValue(xmlwriter);
-
-    const Style cellStyle = style();
-
-    // Either there's no column and row default and the style's not the default \
                style,
-    // or the style is different to one of them. The row default takes precedence.
-    if ((!tableContext.rowDefaultStyles.contains(row) &&
-            !tableContext.columnDefaultStyles.contains(column) &&
-            !(cellStyle.isDefault() && conditions().isEmpty())) ||
-            (tableContext.rowDefaultStyles.contains(row) && \
                tableContext.rowDefaultStyles[row] != cellStyle) ||
-            (tableContext.columnDefaultStyles.contains(column) && \
                tableContext.columnDefaultStyles[column] != cellStyle)) {
-        KoGenStyle currentCellStyle; // the type determined in saveOdfCellStyle
-        QString styleName = saveOdfCellStyle(currentCellStyle, mainStyles);
-        // skip 'table:style-name' attribute for the default style
-        if (!currentCellStyle.isDefaultStyle()) {
-            if (!styleName.isEmpty())
-                xmlwriter.addAttribute("table:style-name", styleName);
-        }
-    }
-
-    // group empty cells with the same style
-    const QString comment = this->comment();
-    if (isEmpty() && comment.isEmpty() && !isPartOfMerged() && !doesMergeCells() &&
-            !tableContext.cellHasAnchoredShapes(sheet(), row, column)) {
-        bool refCellIsDefault = isDefault();
-        int j = column + 1;
-        Cell nextCell = sheet()->cellStorage()->nextInRow(column, row);
-        while (!nextCell.isNull()) {
-            // if
-            //   the next cell is not the adjacent one
-            // or
-            //   the next cell is not empty
-            if (nextCell.column() != j || (!nextCell.isEmpty() || \
                tableContext.cellHasAnchoredShapes(sheet(), row, column))) {
-                if (refCellIsDefault) {
-                    // if the origin cell was a default cell,
-                    // we count the default cells
-                    repeated = nextCell.column() - j + 1;
-
-                    // check if any of the empty/default cells we skipped contained \
                anchored shapes
-                    int shapeColumn = tableContext.nextAnchoredShape(sheet(), row, \
                column);
-                    if (shapeColumn) {
-                        repeated = qMin(repeated, shapeColumn - column);
-                    }
-                }
-                // otherwise we just stop here to process the adjacent
-                // cell in the next iteration of the outer loop
-                // (in Sheet::saveOdfCells)
-                break;
-            }
-
-            if (nextCell.isPartOfMerged() || nextCell.doesMergeCells() ||
-                    !nextCell.comment().isEmpty() || \
                tableContext.cellHasAnchoredShapes(sheet(), row, nextCell.column()) \
                ||
-                    !(nextCell.style() == cellStyle && nextCell.conditions() == \
                conditions())) {
-                break;
-            }
-            ++repeated;
-            // get the next cell and set the index to the adjacent cell
-            nextCell = sheet()->cellStorage()->nextInRow(j++, row);
-        }
-        //debugSheetsODF << "Cell::saveOdf: empty cell in column" << column
-        //<< "repeated" << repeated << "time(s)" << endl;
-
-        if (repeated > 1)
-            xmlwriter.addAttribute("table:number-columns-repeated", \
                QString::number(repeated));
-    }
-
-    Validity validity = Cell(sheet(), column, row).validity();
-    if (!validity.isEmpty()) {
-        GenValidationStyle styleVal(&validity, sheet()->map()->converter());
-        xmlwriter.addAttribute("table:validation-name", \
                tableContext.valStyle.insert(styleVal));
-    }
-    if (isFormula()) {
-        //debugSheetsODF <<"Formula found";
-        QString formula = Odf::encodeFormula(userInput(), locale());
-        xmlwriter.addAttribute("table:formula", formula);
-    }
-
-    if (doesMergeCells()) {
-        int colSpan = mergedXCells() + 1;
-        int rowSpan = mergedYCells() + 1;
-
-        if (colSpan > 1)
-            xmlwriter.addAttribute("table:number-columns-spanned", \
                QString::number(colSpan));
-
-        if (rowSpan > 1)
-            xmlwriter.addAttribute("table:number-rows-spanned", \
                QString::number(rowSpan));
-    }
-
-    saveOdfAnnotation(xmlwriter);
-
-    if (!isFormula() && !link().isEmpty()) {
-        //debugSheetsODF<<"Link found";
-        xmlwriter.startElement("text:p");
-        xmlwriter.startElement("text:a");
-        const QString url = link();
-        //Reference cell is started by '#'
-        if (Util::localReferenceAnchor(url))
-            xmlwriter.addAttribute("xlink:href", ('#' + url));
-        else
-            xmlwriter.addAttribute("xlink:href", url);
-        xmlwriter.addAttribute("xlink:type", "simple");
-        xmlwriter.addTextNode(userInput());
-        xmlwriter.endElement();
-        xmlwriter.endElement();
-    }
-
-    if (!isEmpty() && link().isEmpty()) {
-        QSharedPointer<QTextDocument> doc = richText();
-        if (doc) {
-            QTextCharFormat format = style().asCharFormat();
-            ((KoCharacterStyle \
*)sheet()->map()->textStyleManager()->defaultParagraphStyle())->copyProperties(format);
                
-
-            KoTextWriter writer(tableContext.shapeContext);
-
-            writer.write(doc.data(), 0);
-        } else {
-            xmlwriter.startElement("text:p");
-            xmlwriter.addTextNode(displayText().toUtf8());
-            xmlwriter.endElement();
-        }
-    }
-
-    // flake
-    // Save shapes that are anchored to this cell.
-    // see: OpenDocument, 2.3.1 Text Documents
-    // see: OpenDocument, 9.2 Drawing Shapes
-    if (tableContext.cellHasAnchoredShapes(sheet(), row, column)) {
-        const QList<KoShape*> shapes = tableContext.cellAnchoredShapes(sheet(), row, \
                column);
-        for (int i = 0; i < shapes.count(); ++i) {
-            KoShape* const shape = shapes[i];
-            const QPointF bottomRight = shape->boundingRect().bottomRight();
-            qreal endX = 0.0;
-            qreal endY = 0.0;
-            const int scol = sheet()->leftColumn(bottomRight.x(), endX);
-            const int srow = sheet()->topRow(bottomRight.y(), endY);
-            qreal offsetX = sheet()->columnPosition(column);
-            qreal offsetY = sheet()->rowPosition(row);
-            tableContext.shapeContext.addShapeOffset(shape, \
                QTransform::fromTranslate(-offsetX, -offsetY));
-            shape->setAdditionalAttribute("table:end-cell-address", \
                Region(QPoint(scol, srow)).saveOdf());
-            shape->setAdditionalAttribute("table:end-x", \
                QString::number(bottomRight.x() - endX) + "pt");
-            shape->setAdditionalAttribute("table:end-y", \
                QString::number(bottomRight.y() - endY) + "pt");
-            shape->saveOdf(tableContext.shapeContext);
-            shape->removeAdditionalAttribute("table:end-cell-address");
-            shape->removeAdditionalAttribute("table:end-x");
-            shape->removeAdditionalAttribute("table:end-y");
-            tableContext.shapeContext.removeShapeOffset(shape);
-        }
-    }
-
-    xmlwriter.endElement();
-    return true;
-}
-
-void Cell::saveOdfValue(KoXmlWriter &xmlWriter)
-{
-    // Determine the format that we will be storing.
-    // This is usually the format that is actually shown - doing so mixes style and \
                content, but that's how
-    // LO does it, so we need to stay compatible
-    Format::Type shownFormat = style().formatType();
-    if (shownFormat == Format::Generic)
-        shownFormat = sheet()->map()->formatter()->determineFormatting(value(), \
                shownFormat);
-    Value::Format saveFormat = Value::fmt_None;
-    Value::Format valueFormat = value().format();
-    if (valueFormat == Value::fmt_Boolean)
-        saveFormat = Value::fmt_Boolean;
-    else if (valueFormat == Value::fmt_String)  // if it's a text, it needs to be \
                stored as a text
-        saveFormat = Value::fmt_String;
-    else if (Format::isDate(shownFormat))
-        saveFormat = Value::fmt_Date;
-    else if (Format::isTime(shownFormat))
-        saveFormat = Value::fmt_Time;
-    else if (Format::isNumber(shownFormat))
-        saveFormat = Value::fmt_Number;
-    else if (Format::isMoney(shownFormat))
-        saveFormat = Value::fmt_Money;
-    else if (shownFormat == Format::Percentage)
-        saveFormat = Value::fmt_Percent;
-    else if (shownFormat == Format::Text)
-        saveFormat = Value::fmt_String;
-    else if (shownFormat == Format::Custom)
-        saveFormat = valueFormat;
-
-    switch (saveFormat) {
-    case Value::fmt_None: break;  //NOTHING HERE
-    case Value::fmt_Boolean: {
-        xmlWriter.addAttribute("office:value-type", "boolean");
-        xmlWriter.addAttribute("office:boolean-value", (value().asBoolean() ? "true" \
                : "false"));
-        break;
-    }
-    case Value::fmt_Number: {
-        xmlWriter.addAttribute("office:value-type", "float");
-        if (value().isInteger())
-            xmlWriter.addAttribute("office:value", \
                QString::number(value().asInteger()));
-        else
-            xmlWriter.addAttribute("office:value", \
                QString::number(numToDouble(value().asFloat()), 'g', DBL_DIG));
-        break;
-    }
-    case Value::fmt_Percent: {
-        xmlWriter.addAttribute("office:value-type", "percentage");
-        xmlWriter.addAttribute("office:value", QString::number((double) \
                numToDouble(value().asFloat())));
-        break;
-    }
-    case Value::fmt_Money: {
-        xmlWriter.addAttribute("office:value-type", "currency");
-        const Style style = this->style();
-        if (style.hasAttribute(Style::CurrencyFormat)) {
-            Currency currency = style.currency();
-            xmlWriter.addAttribute("office:currency", currency.code());
-        }
-        xmlWriter.addAttribute("office:value", QString::number((double) \
                numToDouble(value().asFloat())));
-        break;
-    }
-    case Value::fmt_DateTime: break;  //NOTHING HERE
-    case Value::fmt_Date: {
-        xmlWriter.addAttribute("office:value-type", "date");
-        xmlWriter.addAttribute("office:date-value",
-                               \
                value().asDate(sheet()->map()->calculationSettings()).toString(Qt::ISODate));
                
-        break;
-    }
-    case Value::fmt_Time: {
-        xmlWriter.addAttribute("office:value-type", "time");
-        xmlWriter.addAttribute("office:time-value",
-                               value().asTime().toString("'PT'hh'H'mm'M'ss'S'"));
-        break;
-    }
-    case Value::fmt_String: {
-        xmlWriter.addAttribute("office:value-type", "string");
-        xmlWriter.addAttribute("office:string-value", value().asString());
-        break;
-    }
-    };
-}
-
-bool Cell::loadOdf(const KoXmlElement& element, OdfLoadingContext& tableContext,
-            const Styles& autoStyles, const QString& cellStyleName,
-            QList<ShapeLoadingData>& shapeData)
-{
-    static const QString sFormula           = QString::fromLatin1("formula");
-    static const QString sValidationName    = \
                QString::fromLatin1("validation-name");
-    static const QString sValueType         = QString::fromLatin1("value-type");
-    static const QString sBoolean           = QString::fromLatin1("boolean");
-    static const QString sBooleanValue      = QString::fromLatin1("boolean-value");
-    static const QString sTrue              = QString::fromLatin1("true");
-    static const QString sFalse             = QString::fromLatin1("false");
-    static const QString sFloat             = QString::fromLatin1("float");
-    static const QString sValue             = QString::fromLatin1("value");
-    static const QString sCurrency          = QString::fromLatin1("currency");
-    static const QString sPercentage        = QString::fromLatin1("percentage");
-    static const QString sDate              = QString::fromLatin1("date");
-    static const QString sDateValue         = QString::fromLatin1("date-value");
-    static const QString sTime              = QString::fromLatin1("time");
-    static const QString sTimeValue         = QString::fromLatin1("time-value");
-    static const QString sString            = QString::fromLatin1("string");
-    static const QString sStringValue       = QString::fromLatin1("string-value");
-    static const QString sNumberColumnsSpanned = \
                QString::fromLatin1("number-columns-spanned");
-    static const QString sNumberRowsSpanned = \
                QString::fromLatin1("number-rows-spanned");
-    static const QString sAnnotation        = QString::fromLatin1("annotation");
-    static const QString sP                 = QString::fromLatin1("p");
-
-    static const QStringList formulaNSPrefixes = QStringList() << "oooc:" << "kspr:" \
                << "of:" << "msoxl:";
-
-    //Search and load each paragraph of text. Each paragraph is separated by a line \
                break.
-    loadOdfCellText(element, tableContext, autoStyles, cellStyleName);
-
-    //
-    // formula
-    //
-    bool isFormula = false;
-    if (element.hasAttributeNS(KoXmlNS::table, sFormula)) {
-        isFormula = true;
-        QString oasisFormula(element.attributeNS(KoXmlNS::table, sFormula, \
                QString()));
-        // debugSheetsODF << "cell:" << name() << "formula :" << oasisFormula;
-        // each spreadsheet application likes to safe formulas with a different \
                namespace
-        // prefix, so remove all of them
-        QString namespacePrefix;
-        foreach(const QString &prefix, formulaNSPrefixes) {
-            if (oasisFormula.startsWith(prefix)) {
-                oasisFormula.remove(0, prefix.length());
-                namespacePrefix = prefix;
-                break;
-            }
-        }
-        oasisFormula = Odf::decodeFormula(oasisFormula, locale(), namespacePrefix);
-        setUserInput(oasisFormula);
-    } else if (!userInput().isEmpty() && userInput().at(0) == '=')  //prepend ' to \
                the text to avoid = to be painted
-        setUserInput(userInput().prepend('\''));
-
-    //
-    // validation
-    //
-    if (element.hasAttributeNS(KoXmlNS::table, sValidationName)) {
-        const QString validationName = element.attributeNS(KoXmlNS::table, \
                sValidationName, QString());
-        debugSheetsODF << "cell:" << name() << sValidationName << validationName;
-        Validity validity;
-        validity.loadOdfValidation(this, validationName, tableContext);
-        if (!validity.isEmpty())
-            setValidity(validity);
-    }
-
-    //
-    // value type
-    //
-    if (element.hasAttributeNS(KoXmlNS::office, sValueType)) {
-        const QString valuetype = element.attributeNS(KoXmlNS::office, sValueType, \
                QString());
-        // debugSheetsODF << "cell:" << name() << "value-type:" << valuetype;
-        if (valuetype == sBoolean) {
-            const QString val = element.attributeNS(KoXmlNS::office, sBooleanValue, \
                QString()).toLower();
-            if ((val == sTrue) || (val == sFalse))
-                setValue(Value(val == sTrue));
-        }
-
-        // integer and floating-point value
-        else if (valuetype == sFloat) {
-            bool ok = false;
-            Value value(element.attributeNS(KoXmlNS::office, sValue, \
                QString()).toDouble(&ok));
-            if (ok) {
-                value.setFormat(Value::fmt_Number);
-                setValue(value);
-#if 0
-                Style style;
-                style.setFormatType(Format::Number);
-                setStyle(style);
-#endif
-            }
-            // always set the userInput to the actual value read from the cell, and \
not whatever happens to be set as text, as the textual representation of a value may \
                be less accurate than the value itself
-            if (!isFormula)
-                setUserInput(sheet()->map()->converter()->asString(value).asString());
                
-        }
-
-        // currency value
-        else if (valuetype == sCurrency) {
-            bool ok = false;
-            Value value(element.attributeNS(KoXmlNS::office, sValue, \
                QString()).toDouble(&ok));
-            if (ok) {
-                value.setFormat(Value::fmt_Money);
-                setValue(value);
-
-                Currency currency;
-                if (element.hasAttributeNS(KoXmlNS::office, sCurrency)) {
-                    currency = Currency(element.attributeNS(KoXmlNS::office, \
                sCurrency, QString()));
-                }
-                /* TODO: somehow make this work again, all setStyle calls here will \
                be overwritten by cell styles later
-                if( style.isEmpty() ) {
-                    Style style;
-                    style.setCurrency(currency);
-                    setStyle(style);
-                } */
-            }
-        } else if (valuetype == sPercentage) {
-            bool ok = false;
-            Value value(element.attributeNS(KoXmlNS::office, sValue, \
                QString()).toDouble(&ok));
-            if (ok) {
-                value.setFormat(Value::fmt_Percent);
-                setValue(value);
-                if (!isFormula && userInput().isEmpty())
-                    \
                setUserInput(sheet()->map()->converter()->asString(value).asString());
                
-// FIXME Stefan: Should be handled by Value::Format. Verify and remove!
-#if 0
-                Style style;
-                style.setFormatType(Format::Percentage);
-                setStyle(style);
-#endif
-            }
-        } else if (valuetype == sDate) {
-            QString value = element.attributeNS(KoXmlNS::office, sDateValue, \
                QString());
-
-            // "1980-10-15" or "2001-01-01T19:27:41"
-            int year = 0, month = 0, day = 0, hours = 0, minutes = 0, seconds = 0;
-            bool hasTime = false;
-            bool ok = false;
-
-            int p1 = value.indexOf('-');
-            if (p1 > 0) {
-                year  = value.left(p1).toInt(&ok);
-                if (ok) {
-                    int p2 = value.indexOf('-', ++p1);
-                    month = value.mid(p1, p2 - p1).toInt(&ok);
-                    if (ok) {
-                        // the date can optionally have a time attached
-                        int p3 = value.indexOf('T', ++p2);
-                        if (p3 > 0) {
-                            hasTime = true;
-                            day = value.mid(p2, p3 - p2).toInt(&ok);
-                            if (ok) {
-                                int p4 = value.indexOf(':', ++p3);
-                                hours = value.mid(p3, p4 - p3).toInt(&ok);
-                                if (ok) {
-                                    int p5 = value.indexOf(':', ++p4);
-                                    minutes = value.mid(p4, p5 - p4).toInt(&ok);
-                                    if (ok)
-                                        seconds = value.right(value.length() - p5 - \
                1).toInt(&ok);
-                                }
-                            }
-                        } else {
-                            day = value.right(value.length() - p2).toInt(&ok);
-                        }
-                    }
-                }
-            }
-
-            if (ok) {
-                if (hasTime)
-                    setValue(Value(QDateTime(QDate(year, month, day), QTime(hours, \
                minutes, seconds)), sheet()->map()->calculationSettings()));
-                else
-                    setValue(Value(QDate(year, month, day), \
                sheet()->map()->calculationSettings()));
-// FIXME Stefan: Should be handled by Value::Format. Verify and remove!
-//Sebsauer: Fixed now. Value::Format handles it correct.
-#if 0
-                Style s;
-                s.setFormatType(Format::ShortDate);
-                setStyle(s);
-#endif
-                // debugSheetsODF << "cell:" << name() << "Type: date, value:" << \
                value << "Date:" << year << " -" << month << " -" << day;
-            }
-        } else if (valuetype == sTime) {
-            QString value = element.attributeNS(KoXmlNS::office, sTimeValue, \
                QString());
-
-            // "PT15H10M12S"
-            int hours = 0, minutes = 0, seconds = 0;
-            int l = value.length();
-            QString num;
-            bool ok = false;
-            for (int i = 0; i < l; ++i) {
-                if (value[i].isNumber()) {
-                    num += value[i];
-                    continue;
-                } else if (value[i] == 'H')
-                    hours   = num.toInt(&ok);
-                else if (value[i] == 'M')
-                    minutes = num.toInt(&ok);
-                else if (value[i] == 'S')
-                    seconds = num.toInt(&ok);
-                else
-                    continue;
-                //debugSheetsODF << "Num:" << num;
-                num.clear();
-                if (!ok)
-                    break;
-            }
-
-            if (ok) {
-                // Value kval( timeToNum( hours, minutes, seconds ) );
-                // cell.setValue( kval );
-                setValue(Value(QTime(hours % 24, minutes, seconds)));
-// FIXME Stefan: Should be handled by Value::Format. Verify and remove!
-#if 0
-                Style style;
-                style.setFormatType(Format::Time);
-                setStyle(style);
-#endif
-                // debugSheetsODF << "cell:" << name() << "Type: time:" << value << \
                "Hours:" << hours << "," << minutes << "," << seconds;
-            }
-        } else if (valuetype == sString) {
-            if (element.hasAttributeNS(KoXmlNS::office, sStringValue)) {
-                QString value = element.attributeNS(KoXmlNS::office, sStringValue, \
                QString());
-                setValue(Value(value));
-            } else {
-                // use the paragraph(s) read in before
-                setValue(Value(userInput()));
-            }
-// FIXME Stefan: Should be handled by Value::Format. Verify and remove!
-#if 0
-            Style style;
-            style.setFormatType(Format::Text);
-            setStyle(style);
-#endif
-        } else {
-            // debugSheetsODF << "cell:" << name() << "  Unknown type. Parsing user \
                input.";
-            // Set the value by parsing the user input.
-            parseUserInput(userInput());
-        }
-    } else { // no value-type attribute
-        // debugSheetsODF << "cell:" << name() << "  No value type specified. \
                Parsing user input.";
-        // Set the value by parsing the user input.
-        parseUserInput(userInput());
-    }
-
-    //
-    // merged cells ?
-    //
-    int colSpan = 1;
-    int rowSpan = 1;
-    if (element.hasAttributeNS(KoXmlNS::table, sNumberColumnsSpanned)) {
-        bool ok = false;
-        int span = element.attributeNS(KoXmlNS::table, sNumberColumnsSpanned, \
                QString()).toInt(&ok);
-        if (ok) colSpan = span;
-    }
-    if (element.hasAttributeNS(KoXmlNS::table, sNumberRowsSpanned)) {
-        bool ok = false;
-        int span = element.attributeNS(KoXmlNS::table, sNumberRowsSpanned, \
                QString()).toInt(&ok);
-        if (ok) rowSpan = span;
-    }
-    if (colSpan > 1 || rowSpan > 1)
-        mergeCells(d->column, d->row, colSpan - 1, rowSpan - 1);
-
-    //
-    // cell comment/annotation
-    //
-    KoXmlElement annotationElement = KoXml::namedItemNS(element, KoXmlNS::office, \
                sAnnotation);
-    if (!annotationElement.isNull()) {
-        QString comment;
-        KoXmlNode node = annotationElement.firstChild();
-        while (!node.isNull()) {
-            KoXmlElement commentElement = node.toElement();
-            if (!commentElement.isNull())
-                if (commentElement.localName() == sP && \
                commentElement.namespaceURI() == KoXmlNS::text) {
-                    if (!comment.isEmpty()) comment.append('\n');
-                    comment.append(commentElement.text());
-                }
-
-            node = node.nextSibling();
-        }
-        if (!comment.isEmpty())
-            setComment(comment);
-    }
-
-    loadOdfObjects(element, tableContext, shapeData);
-
-    return true;
-}
-
-// Similar to KoXml::namedItemNS except that children of span tags will be evaluated \
                too.
-KoXmlElement namedItemNSWithSpan(const KoXmlNode& node, const QString &nsURI, const \
                QString &localName)
-{
-    KoXmlNode n = node.firstChild();
-    for (; !n.isNull(); n = n.nextSibling()) {
-        if (n.isElement()) {
-            if (n.localName() == localName && n.namespaceURI() == nsURI) {
-                return n.toElement();
-            }
-            if (n.localName() == "span" && n.namespaceURI() == nsURI) {
-                KoXmlElement e = KoXml::namedItemNS(n, nsURI, localName); // not \
                recursive
-                if (!e.isNull()) {
-                    return e;
-                }
-            }
-        }
-    }
-    return KoXmlElement();
-}
-
-// recursively goes through all children of parent and returns true if there is any \
                element
-// in the draw: namespace in this subtree
-static bool findDrawElements(const KoXmlElement& parent)
-{
-    KoXmlElement element;
-    forEachElement(element , parent) {
-        if (element.namespaceURI() == KoXmlNS::draw)
-            return true;
-        if (findDrawElements(element))
-            return true;
-    }
-    return false;
-}
-
-QString loadOdfCellTextNodes(const KoXmlElement& element, int *textFragmentCount, \
                int *lineCount, bool *hasRichText, bool *stripLeadingSpace)
-{
-    QString cellText;
-    bool countedOwnFragments = false;
-    bool prevWasText = false;
-    for (KoXmlNode n = element.firstChild(); !n.isNull(); n = n.nextSibling()) {
-        if (n.isText()) {
-            prevWasText = true;
-            QString t = KoTextLoader::normalizeWhitespace(n.toText().data(), \
                *stripLeadingSpace);
-            if (!t.isEmpty()) {
-                *stripLeadingSpace = t[t.length() - 1].isSpace();
-                cellText += t;
-                if (!countedOwnFragments) {
-                    // We only count the number of different parent elements which \
                have text. That is
-                    // so cause different parent-elements may mean different styles \
                which means
-                    // rich-text while the same parent element means the same style \
                so we can easily
-                    // put them together into one string.
-                    countedOwnFragments = true;
-                    ++(*textFragmentCount);
-                }
-            }
-        } else {
-            KoXmlElement e = n.toElement();
-            if (!e.isNull()) {
-                if (prevWasText && !cellText.isEmpty() && cellText[cellText.length() \
                - 1].isSpace()) {
-                    // A trailing space of the cellText collected so far needs to be \
                preserved when
-                    // more text-nodes within the same parent follow but if an \
                element like e.g.
-                    // text:s follows then a trailing space needs to be removed.
-                    cellText.chop(1);
-                }
-                prevWasText = false;
-
-                // We can optimize some elements like text:s (space), text:tab \
                (tabulator) and
-                // text:line-break (new-line) to not produce rich-text but add the \
                equivalent
-                // for them in plain-text.
-                const bool isTextNs = e.namespaceURI() == KoXmlNS::text;
-                if (isTextNs && e.localName() == "s") {
-                    const int howmany = qMax(1, e.attributeNS(KoXmlNS::text, "c", \
                QString()).toInt());
-                    cellText += QString().fill(32, howmany);
-                } else if (isTextNs && e.localName() == "tab") {
-                    cellText += '\t';
-                } else if (isTextNs && e.localName() == "line-break") {
-                    cellText += '\n';
-                    ++(*lineCount);
-                } else if (isTextNs && e.localName() == "span") {
-                    // Nested span-elements means recursive evaluation.
-                    cellText += loadOdfCellTextNodes(e, textFragmentCount, \
                lineCount, hasRichText, stripLeadingSpace);
-                } else if (!isTextNs ||
-                              ( e.localName() != "annotation" &&
-                                e.localName() != "bookmark" &&
-                                e.localName() != "meta" &&
-                                e.localName() != "tag" )) {
-                    // Seems we have an element we cannot easily translate to a \
                string what
-                    // means it's all rich-text now.
-                    *hasRichText = true;
-                }
-            }
-        }
-    }
-    return cellText;
-}
-
-void Cell::loadOdfCellText(const KoXmlElement& parent, OdfLoadingContext& \
                tableContext, const Styles& autoStyles, const QString& cellStyleName)
-{
-    //Search and load each paragraph of text. Each paragraph is separated by a line \
                break
-    KoXmlElement textParagraphElement;
-    QString cellText;
-
-    int lineCount = 0;
-    bool hasRichText = false;
-    bool stripLeadingSpace = true;
-
-    forEachElement(textParagraphElement , parent) {
-        if (textParagraphElement.localName() == "p" &&
-                textParagraphElement.namespaceURI() == KoXmlNS::text) {
-
-            // the text:a link could be located within a text:span element
-            KoXmlElement textA = namedItemNSWithSpan(textParagraphElement, \
                KoXmlNS::text, "a");
-            if (!textA.isNull() && textA.hasAttributeNS(KoXmlNS::xlink, "href")) {
-                QString link = textA.attributeNS(KoXmlNS::xlink, "href", QString());
-                cellText = textA.text();
-                setUserInput(cellText);
-                hasRichText = false;
-                lineCount = 0;
-                // The value will be set later in loadOdf().
-                if ((!link.isEmpty()) && (link[0] == '#'))
-                    link.remove(0, 1);
-                setLink(link);
-                // Abort here cause we can handle only either a link in a cell or \
                (rich-)text but not both.
-                break;
-            }
-
-            if (!cellText.isNull())
-                cellText += '\n';
-
-            ++lineCount;
-            int textFragmentCount = 0;
-
-            // Our text could contain formating for value or result of formula or a \
                mix of
-            // multiple text:span elements with text-nodes and line-break's.
-            cellText += loadOdfCellTextNodes(textParagraphElement, \
                &textFragmentCount, &lineCount, &hasRichText, &stripLeadingSpace);
-
-            // If we got text from multiple different sources (e.g. from the text:p \
                and a
-            // child text:span) then we have very likely rich-text.
-            if (!hasRichText)
-                hasRichText = textFragmentCount >= 2;
-        }
-    }
-
-    if (!cellText.isNull()) {
-        if (hasRichText && !findDrawElements(parent)) {
-            // for now we don't support richtext and embedded shapes in the same \
                cell;
-            // this is because they would currently be loaded twice, once by the \
                KoTextLoader
-            // and later properly by the cell itself
-
-            Style style; style.setDefault();
-            if (!cellStyleName.isEmpty()) {
-                if (autoStyles.contains(cellStyleName))
-                    style.merge(autoStyles[cellStyleName]);
-                else {
-                    const CustomStyle* namedStyle = \
                sheet()->map()->styleManager()->style(cellStyleName);
-                    if (namedStyle)
-                        style.merge(*namedStyle);
-                }
-            }
-
-            QTextCharFormat format = style.asCharFormat();
-            ((KoCharacterStyle \
*)sheet()->map()->textStyleManager()->defaultParagraphStyle())->copyProperties(format);
                
-
-            QSharedPointer<QTextDocument> doc(new QTextDocument);
-            KoTextDocument(doc.data()).setStyleManager(sheet()->map()->textStyleManager());
                
-
-            Q_ASSERT(tableContext.shapeContext);
-            KoTextLoader loader(*tableContext.shapeContext);
-            QTextCursor cursor(doc.data());
-            loader.loadBody(parent, cursor);
-
-            setUserInput(doc->toPlainText());
-            setRichText(doc);
-        } else {
-            setUserInput(cellText);
-        }
-    }
-
-    // enable word wrapping if multiple lines of text have been found.
-    if (lineCount >= 2) {
-        Style newStyle;
-        newStyle.setWrapText(true);
-        setStyle(newStyle);
-    }
-}
-
-void Cell::loadOdfObjects(const KoXmlElement &parent, OdfLoadingContext& \
                tableContext, QList<ShapeLoadingData>& shapeData)
-{
-    // Register additional attributes, that identify shapes anchored in cells.
-    // Their dimensions need adjustment after all rows are loaded,
-    // because the position of the end cell is not always known yet.
-    KoShapeLoadingContext::addAdditionalAttributeData(KoShapeLoadingContext::AdditionalAttributeData(
                
-                KoXmlNS::table, "end-cell-address",
-                "table:end-cell-address"));
-    KoShapeLoadingContext::addAdditionalAttributeData(KoShapeLoadingContext::AdditionalAttributeData(
                
-                KoXmlNS::table, "end-x",
-                "table:end-x"));
-    KoShapeLoadingContext::addAdditionalAttributeData(KoShapeLoadingContext::AdditionalAttributeData(
                
-                KoXmlNS::table, "end-y",
-                "table:end-y"));
-
-    KoXmlElement element;
-    forEachElement(element, parent) {
-        if (element.namespaceURI() != KoXmlNS::draw)
-            continue;
-
-        if (element.localName() == "a") {
-            // It may the case that the object(s) are embedded into a hyperlink so \
                actions are done on
-            // clicking it/them but since we do not supported \
                objects-with-hyperlinks yet we just fetch
-            // the inner elements and use them to at least create and show the \
                objects (see bug 249862).
-            KoXmlElement e;
-            forEachElement(e, element) {
-                if (e.namespaceURI() != KoXmlNS::draw)
-                    continue;
-                ShapeLoadingData data = loadOdfObject(e, \
                *tableContext.shapeContext);
-                if (data.shape) {
-                    shapeData.append(data);
-                }
-            }
-        } else {
-            ShapeLoadingData data = loadOdfObject(element, \
                *tableContext.shapeContext);
-            if (data.shape) {
-                shapeData.append(data);
-            }
-        }
-    }
-}
-
-ShapeLoadingData Cell::loadOdfObject(const KoXmlElement &element, \
                KoShapeLoadingContext &shapeContext)
-{
-    ShapeLoadingData data;
-    data.shape = 0;
-    KoShape* shape = KoShapeRegistry::instance()->createShapeFromOdf(element, \
                shapeContext);
-    if (!shape) {
-        debugSheetsODF << "Unable to load shape with localName=" << \
                element.localName();
-        return data;
-    }
-
-    d->sheet->addShape(shape);
-
-    // The position is relative to the upper left sheet corner until now. Move it.
-    QPointF position = shape->position();
-    // Remember how far we're off from the top-left corner of this cell
-    double offsetX = position.x();
-    double offsetY = position.y();
-    for (int col = 1; col < column(); ++col)
-        position += QPointF(d->sheet->columnFormat(col)->width(), 0.0);
-    if (this->row() > 1)
-        position += QPointF(0.0, d->sheet->rowFormats()->totalRowHeight(1, \
                this->row() - 1));
-    shape->setPosition(position);
-
-    dynamic_cast<ShapeApplicationData*>(shape->applicationData())->setAnchoredToCell(true);
                
-
-    // All three attributes are necessary for cell anchored shapes.
-    // Otherwise, they are anchored in the sheet.
-    if (!shape->hasAdditionalAttribute("table:end-cell-address") ||
-            !shape->hasAdditionalAttribute("table:end-x") ||
-            !shape->hasAdditionalAttribute("table:end-y")) {
-        debugSheetsODF << "Not all attributes found, that are necessary for cell \
                anchoring.";
-        return data;
-    }
-
-    Region endCell(Region::loadOdf(shape->additionalAttribute("table:end-cell-address")),
                
-                   d->sheet->map(), d->sheet);
-    if (!endCell.isValid() || !endCell.isSingular())
-        return data;
-
-    QString string = shape->additionalAttribute("table:end-x");
-    if (string.isNull())
-        return data;
-    double endX = KoUnit::parseValue(string);
-
-    string = shape->additionalAttribute("table:end-y");
-    if (string.isNull())
-        return data;
-    double endY = KoUnit::parseValue(string);
-
-    data.shape = shape;
-    data.startCell = QPoint(column(), row());
-    data.offset = QPointF(offsetX, offsetY);
-    data.endCell = endCell;
-    data.endPoint = QPointF(endX, endY);
-
-    // The column dimensions are already the final ones, but not the row dimensions.
-    // The default height is used for the not yet loaded rows.
-    // TODO Stefan: Honor non-default row heights later!
-    // subtract offset because the accumulated width and height we calculate below \
                starts
-    // at the top-left corner of this cell, but the shape can have an offset to that \
                corner
-    QSizeF size = QSizeF(endX - offsetX, endY - offsetY);
-    for (int col = column(); col < endCell.firstRange().left(); ++col)
-        size += QSizeF(d->sheet->columnFormat(col)->width(), 0.0);
-    if (endCell.firstRange().top() > this->row())
-        size += QSizeF(0.0, d->sheet->rowFormats()->totalRowHeight(this->row(), \
                endCell.firstRange().top() - 1));
-    shape->setSize(size);
-
-    return data;
-}
-
 bool Cell::load(const KoXmlElement & cell, int _xshift, int _yshift,
                 Paste::Mode mode, Paste::Operation op, bool paste)
 {
diff --git a/sheets/Cell.h b/sheets/Cell.h
index de62343..c939f8b 100644
--- a/sheets/Cell.h
+++ b/sheets/Cell.h
@@ -49,10 +49,6 @@ class QPoint;
 class QDate;
 
 class KLocale;
-class KoXmlWriter;
-class KoGenStyles;
-class KoGenStyle;
-class KoShapeLoadingContext;
 
 namespace Calligra
 {
@@ -62,13 +58,10 @@ class Conditions;
 class Database;
 class Doc;
 class Formula;
-class OdfLoadingContext;
-class OdfSavingContext;
 class Sheet;
 class Validity;
 class Value;
 class CellTest;
-struct ShapeLoadingData;
 
 /**
  * An accessor to the actual cell data.
@@ -361,22 +354,6 @@ public:
     QDate toDate(const KoXmlElement &element);
 
     /**
-     * \ingroup OpenDocument
-     * Loads a cell from an OASIS XML element.
-     * @param element An OASIS XML element
-     * @param tableContext The loading context assoiated with the XML element
-     */
-    bool loadOdf(const KoXmlElement& element, OdfLoadingContext& tableContext,
-        const Styles& autoStyles, const QString& cellStyleName,
-        QList<ShapeLoadingData>& shapeData);
-
-    /**
-     * \ingroup OpenDocument
-     */
-    bool saveOdf(int row, int column, int &repeated,
-                 OdfSavingContext& savingContext);
-
-    /**
      * Copies the format from \p cell .
      *
      * @see copyAll(Cell *cell)
@@ -596,26 +573,6 @@ public:
      */
     bool compareData(const Cell& other) const;
 
-protected:
-    /**
-     * \ingroup OpenDocument
-     * Load the text paragraphs from an OASIS XML cell description.
-     * @param parent The DOM element representing the cell.
-     */
-    void loadOdfCellText(const KoXmlElement& parent, OdfLoadingContext& \
                tableContext, const Styles& autoStyles, const QString& \
                cellStyleName);
-
-    /**
-     * \ingroup OpenDocument
-     */
-    void loadOdfObjects(const KoXmlElement& e, OdfLoadingContext& tableContext, \
                QList<ShapeLoadingData>& shapeData);
-
-
-    /**
-     * \ingroup OpenDocument
-     */
-    void saveOdfAnnotation(KoXmlWriter &xmlwriter);
-public:
-    ShapeLoadingData loadOdfObject(const KoXmlElement& element, \
KoShapeLoadingContext& shapeContext);  private:
     friend class CellTest;
 
@@ -631,17 +588,6 @@ private:
      * \ingroup NativeFormat
      */
     bool saveCellResult(QDomDocument& doc, QDomElement& result, QString str);
-
-    /**
-     * \ingroup OpenDocument
-     */
-    void saveOdfValue(KoXmlWriter &xmlWriter);
-
-    /**
-     * \ingroup OpenDocument
-     * @return the OASIS style's name
-     */
-    QString saveOdfCellStyle(KoGenStyle &currentCellStyle, KoGenStyles &mainStyles);
 };
 
 inline uint qHash(const Cell& cell)
diff --git a/sheets/Style.cpp b/sheets/Style.cpp
index 68dcc9c..74b8f2b 100644
--- a/sheets/Style.cpp
+++ b/sheets/Style.cpp
@@ -355,6 +355,81 @@ void Style::loadOdfDataStyle(KoOdfStylesReader &stylesReader, \
const QString &sty  }
 }
 
+QString encodePen(const QPen & pen)
+{
+//     debugSheets<<"encodePen( const QPen & pen ) :"<<pen;
+    // NOTE Stefan: QPen api docs:
+    //              A line width of zero indicates a cosmetic pen. This means
+    //              that the pen width is always drawn one pixel wide,
+    //              independent of the transformation set on the painter.
+    QString s = QString("%1pt ").arg((pen.width() == 0) ? 1 : pen.width());
+    switch (pen.style()) {
+    case Qt::NoPen:
+        return "none";
+    case Qt::SolidLine:
+        s += "solid";
+        break;
+    case Qt::DashLine:
+        s += "dashed";
+        break;
+    case Qt::DotLine:
+        s += "dotted";
+        break;
+    case Qt::DashDotLine:
+        s += "dot-dash";
+        break;
+    case Qt::DashDotDotLine:
+        s += "dot-dot-dash";
+        break;
+    default: break;
+    }
+    //debugSheets << " encodePen :" << s;
+    if (pen.color().isValid()) {
+        s += ' ' + Style::colorName(pen.color());
+    }
+    return s;
+}
+
+QPen decodePen(const QString &border)
+{
+    QPen pen;
+    //string like "0.088cm solid #800000"
+    if (border.isEmpty() || border == "none" || border == "hidden") { // in fact no \
border +        pen.setStyle(Qt::NoPen);
+        return pen;
+    }
+    //code from koborder, for the moment Calligra Sheets doesn't use koborder
+    // ## isn't it faster to use QStringList::split than parse it 3 times?
+    QString _width = border.section(' ', 0, 0);
+    QByteArray _style = border.section(' ', 1, 1).toLatin1();
+    QString _color = border.section(' ', 2, 2);
+
+    pen.setWidth((int)(KoUnit::parseValue(_width, 1.0)));
+
+    if (_style == "none")
+        pen.setStyle(Qt::NoPen);
+    else if (_style == "solid")
+        pen.setStyle(Qt::SolidLine);
+    else if (_style == "dashed")
+        pen.setStyle(Qt::DashLine);
+    else if (_style == "dotted")
+        pen.setStyle(Qt::DotLine);
+    else if (_style == "dot-dash")
+        pen.setStyle(Qt::DashDotLine);
+    else if (_style == "dot-dot-dash")
+        pen.setStyle(Qt::DashDotDotLine);
+    else
+        debugSheets << " style undefined :" << _style;
+
+    if (_color.isEmpty())
+        pen.setColor(QColor());
+    else
+        pen.setColor(QColor(_color));
+
+    return pen;
+}
+
+
 void Style::loadOdfParagraphProperties(KoOdfStylesReader& stylesReader, const \
KoStyleStack& styleStack)  {
     Q_UNUSED(stylesReader);
@@ -455,7 +530,7 @@ void Style::loadOdfTableCellProperties(KoOdfStylesReader& \
stylesReader, const Ko  }
     if (styleStack.hasProperty(KoXmlNS::fo, "border")) {
         str = styleStack.property(KoXmlNS::fo, "border");
-        QPen pen = Odf::decodePen(str);
+        QPen pen = decodePen(str);
         setLeftBorderPen(pen);
         setTopBorderPen(pen);
         setBottomBorderPen(pen);
@@ -463,27 +538,27 @@ void Style::loadOdfTableCellProperties(KoOdfStylesReader& \
stylesReader, const Ko  }
     if (styleStack.hasProperty(KoXmlNS::fo, "border-left")) {
         str = styleStack.property(KoXmlNS::fo, "border-left");
-        setLeftBorderPen(Odf::decodePen(str));
+        setLeftBorderPen(decodePen(str));
     }
     if (styleStack.hasProperty(KoXmlNS::fo, "border-right")) {
         str = styleStack.property(KoXmlNS::fo, "border-right");
-        setRightBorderPen(Odf::decodePen(str));
+        setRightBorderPen(decodePen(str));
     }
     if (styleStack.hasProperty(KoXmlNS::fo, "border-top")) {
         str = styleStack.property(KoXmlNS::fo, "border-top");
-        setTopBorderPen(Odf::decodePen(str));
+        setTopBorderPen(decodePen(str));
     }
     if (styleStack.hasProperty(KoXmlNS::fo, "border-bottom")) {
         str = styleStack.property(KoXmlNS::fo, "border-bottom");
-        setBottomBorderPen(Odf::decodePen(str));
+        setBottomBorderPen(decodePen(str));
     }
     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-tl-br")) {
         str = styleStack.property(KoXmlNS::style, "diagonal-tl-br");
-        setFallDiagonalPen(Odf::decodePen(str));
+        setFallDiagonalPen(decodePen(str));
     }
     if (styleStack.hasProperty(KoXmlNS::style, "diagonal-bl-tr")) {
         str = styleStack.property(KoXmlNS::style, "diagonal-bl-tr");
-        setGoUpDiagonalPen(Odf::decodePen(str));
+        setGoUpDiagonalPen(decodePen(str));
     }
 
     if (styleStack.hasProperty(KoXmlNS::draw, "style-name") || \
styleStack.hasProperty(KoXmlNS::calligra, "fill-style-name")) { @@ -1378,25 +1453,25 \
@@ void Style::saveOdfStyle(const QSet<Key>& keysToStore, KoGenStyle &style,  \
(leftBorderPen() == rightBorderPen()) &&  (leftBorderPen() == bottomBorderPen())) {
         if (leftBorderPen().style() != Qt::NoPen)
-            style.addProperty("fo:border", Odf::encodePen(leftBorderPen()));
+            style.addProperty("fo:border", encodePen(leftBorderPen()));
     } else {
         if (keysToStore.contains(LeftPen) && (leftBorderPen().style() != Qt::NoPen))
-            style.addProperty("fo:border-left", Odf::encodePen(leftBorderPen()));
+            style.addProperty("fo:border-left", encodePen(leftBorderPen()));
 
         if (keysToStore.contains(RightPen) && (rightBorderPen().style() != \
                Qt::NoPen))
-            style.addProperty("fo:border-right", Odf::encodePen(rightBorderPen()));
+            style.addProperty("fo:border-right", encodePen(rightBorderPen()));
 
         if (keysToStore.contains(TopPen) && (topBorderPen().style() != Qt::NoPen))
-            style.addProperty("fo:border-top", Odf::encodePen(topBorderPen()));
+            style.addProperty("fo:border-top", encodePen(topBorderPen()));
 
         if (keysToStore.contains(BottomPen) && (bottomBorderPen().style() != \
                Qt::NoPen))
-            style.addProperty("fo:border-bottom", \
Odf::encodePen(bottomBorderPen())); +            \
style.addProperty("fo:border-bottom", encodePen(bottomBorderPen()));  }
     if (keysToStore.contains(FallDiagonalPen) && (fallDiagonalPen().style() != \
                Qt::NoPen)) {
-        style.addProperty("style:diagonal-tl-br", \
Odf::encodePen(fallDiagonalPen())); +        \
style.addProperty("style:diagonal-tl-br", encodePen(fallDiagonalPen()));  }
     if (keysToStore.contains(GoUpDiagonalPen) && (goUpDiagonalPen().style() != \
                Qt::NoPen)) {
-        style.addProperty("style:diagonal-bl-tr", \
Odf::encodePen(goUpDiagonalPen())); +        \
style.addProperty("style:diagonal-bl-tr", encodePen(goUpDiagonalPen()));  }
 
     // font
diff --git a/sheets/Util.cpp b/sheets/Util.cpp
index f125782..903d641 100644
--- a/sheets/Util.cpp
+++ b/sheets/Util.cpp
@@ -321,80 +321,6 @@ QString Calligra::Sheets::Odf::convertRangeToRef(const QString & \
                sheetName, cons
     return sheetName + '.' + Cell::name(_area.left(), _area.top()) + ':' + sheetName \
+ '.' + Cell::name(_area.right(), _area.bottom());  }
 
-QString Calligra::Sheets::Odf::encodePen(const QPen & pen)
-{
-//     debugSheets<<"encodePen( const QPen & pen ) :"<<pen;
-    // NOTE Stefan: QPen api docs:
-    //              A line width of zero indicates a cosmetic pen. This means
-    //              that the pen width is always drawn one pixel wide,
-    //              independent of the transformation set on the painter.
-    QString s = QString("%1pt ").arg((pen.width() == 0) ? 1 : pen.width());
-    switch (pen.style()) {
-    case Qt::NoPen:
-        return "none";
-    case Qt::SolidLine:
-        s += "solid";
-        break;
-    case Qt::DashLine:
-        s += "dashed";
-        break;
-    case Qt::DotLine:
-        s += "dotted";
-        break;
-    case Qt::DashDotLine:
-        s += "dot-dash";
-        break;
-    case Qt::DashDotDotLine:
-        s += "dot-dot-dash";
-        break;
-    default: break;
-    }
-    //debugSheets << " encodePen :" << s;
-    if (pen.color().isValid()) {
-        s += ' ' + Style::colorName(pen.color());
-    }
-    return s;
-}
-
-QPen Calligra::Sheets::Odf::decodePen(const QString &border)
-{
-    QPen pen;
-    //string like "0.088cm solid #800000"
-    if (border.isEmpty() || border == "none" || border == "hidden") { // in fact no \
                border
-        pen.setStyle(Qt::NoPen);
-        return pen;
-    }
-    //code from koborder, for the moment Calligra Sheets doesn't use koborder
-    // ## isn't it faster to use QStringList::split than parse it 3 times?
-    QString _width = border.section(' ', 0, 0);
-    QByteArray _style = border.section(' ', 1, 1).toLatin1();
-    QString _color = border.section(' ', 2, 2);
-
-    pen.setWidth((int)(KoUnit::parseValue(_width, 1.0)));
-
-    if (_style == "none")
-        pen.setStyle(Qt::NoPen);
-    else if (_style == "solid")
-        pen.setStyle(Qt::SolidLine);
-    else if (_style == "dashed")
-        pen.setStyle(Qt::DashLine);
-    else if (_style == "dotted")
-        pen.setStyle(Qt::DotLine);
-    else if (_style == "dot-dash")
-        pen.setStyle(Qt::DashDotLine);
-    else if (_style == "dot-dot-dash")
-        pen.setStyle(Qt::DashDotDotLine);
-    else
-        debugSheets << " style undefined :" << _style;
-
-    if (_color.isEmpty())
-        pen.setColor(QColor());
-    else
-        pen.setColor(QColor(_color));
-
-    return pen;
-}
-
 //Return true when it's a reference to cell from sheet.
 bool Calligra::Sheets::Util::localReferenceAnchor(const QString &_ref)
 {
diff --git a/sheets/Util.h b/sheets/Util.h
index 0a334e0..706c4c4 100644
--- a/sheets/Util.h
+++ b/sheets/Util.h
@@ -132,20 +132,6 @@ namespace Odf
 {
 /**
  * \ingroup OpenDocument
- * Creates OpenDocument pen attributes of the QPen \p pen .
- * \return the OpenDocument pen attributes
- */
-QString encodePen(const QPen& pen);
-
-/**
- * \ingroup OpenDocument
- * Creates a QPen of OpenDocument pen attributes \p str .
- * \return the created QPen
- */
-QPen decodePen(const QString &str);
-
-/**
- * \ingroup OpenDocument
  * Converts an OpenDocument representation of a formula to a localized formula.
  * @param expr The expression to convert from OpenDocument format.
  * @param locale The locale to which the expression should be converted.
diff --git a/sheets/odf/SheetsOdfCell.cpp b/sheets/odf/SheetsOdfCell.cpp
index ffc428a..da16d69 100644
--- a/sheets/odf/SheetsOdfCell.cpp
+++ b/sheets/odf/SheetsOdfCell.cpp
@@ -33,12 +33,946 @@
 
 #include "SheetsOdf.h"
 
+#include <KoGenStyles.h>
+#include <KoShape.h>
+#include <KoShapeLoadingContext.h>
+#include <KoShapeRegistry.h>
+#include <KoStyleManager.h>
+#include <KoTextDocument.h>
+#include <KoTextLoader.h>
+#include <KoTextSharedLoadingData.h>
+#include <KoTextWriter.h>
+#include <KoUnit.h>
+#include <KoXmlNS.h>
+#include <KoXmlWriter.h>
+
+#include "Cell.h"
+#include "CellStorage.h"
+#include "Condition.h"
+#include "Map.h"
+#include "Sheet.h"
+#include "Util.h"
+#include "Value.h"
+#include "ValueFormatter.h"
+#include "GenValidationStyle.h"
+#include "OdfLoadingContext.h"
+#include "OdfSavingContext.h"
+#include "ShapeApplicationData.h"
+
 // This file contains functionality to load/save a Cell
 
 namespace Calligra {
 namespace Sheets {
 
 
+namespace Odf {
+    bool loadCell(Cell *cell, const KoXmlElement& element, OdfLoadingContext& \
tableContext, +            const Styles& autoStyles, const QString& cellStyleName,
+            QList<ShapeLoadingData>& shapeData);
+    bool saveCell(Cell *cell, int &repeated, OdfSavingContext& tableContext);
+
+    // cell loading - helper functions
+    void loadCellText(Cell *cell, const KoXmlElement& parent, OdfLoadingContext& \
tableContext, const Styles& autoStyles, const QString& cellStyleName); +    QString \
loadCellTextNodes(Cell *cell, const KoXmlElement& element, int *textFragmentCount, \
int *lineCount, bool *hasRichText, bool *stripLeadingSpace); +    void \
loadObjects(Cell *cell, const KoXmlElement &parent, OdfLoadingContext& tableContext, \
QList<ShapeLoadingData>& shapeData); +    ShapeLoadingData loadObject(Cell *cell, \
const KoXmlElement &element, KoShapeLoadingContext &shapeContext); +
+    // cell saving - helper functions
+    QString saveCellStyle(Cell *cell, KoGenStyle &currentCellStyle, KoGenStyles \
&mainStyles); +    void saveCellAnnotation(Cell *cell, KoXmlWriter &xmlwriter);
+    void saveCellValue(Cell *cell, KoXmlWriter &xmlWriter);
+}
+
+// *************** Loading *****************
+bool Odf::loadCell(Cell *cell, const KoXmlElement& element, OdfLoadingContext& \
tableContext, +            const Styles& autoStyles, const QString& cellStyleName,
+            QList<ShapeLoadingData>& shapeData)
+{
+    static const QString sFormula           = QString::fromLatin1("formula");
+    static const QString sValidationName    = \
QString::fromLatin1("validation-name"); +    static const QString sValueType         \
= QString::fromLatin1("value-type"); +    static const QString sBoolean           = \
QString::fromLatin1("boolean"); +    static const QString sBooleanValue      = \
QString::fromLatin1("boolean-value"); +    static const QString sTrue              = \
QString::fromLatin1("true"); +    static const QString sFalse             = \
QString::fromLatin1("false"); +    static const QString sFloat             = \
QString::fromLatin1("float"); +    static const QString sValue             = \
QString::fromLatin1("value"); +    static const QString sCurrency          = \
QString::fromLatin1("currency"); +    static const QString sPercentage        = \
QString::fromLatin1("percentage"); +    static const QString sDate              = \
QString::fromLatin1("date"); +    static const QString sDateValue         = \
QString::fromLatin1("date-value"); +    static const QString sTime              = \
QString::fromLatin1("time"); +    static const QString sTimeValue         = \
QString::fromLatin1("time-value"); +    static const QString sString            = \
QString::fromLatin1("string"); +    static const QString sStringValue       = \
QString::fromLatin1("string-value"); +    static const QString sNumberColumnsSpanned \
= QString::fromLatin1("number-columns-spanned"); +    static const QString \
sNumberRowsSpanned = QString::fromLatin1("number-rows-spanned"); +    static const \
QString sAnnotation        = QString::fromLatin1("annotation"); +    static const \
QString sP                 = QString::fromLatin1("p"); +
+    static const QStringList formulaNSPrefixes = QStringList() << "oooc:" << "kspr:" \
<< "of:" << "msoxl:"; +
+    //Search and load each paragraph of text. Each paragraph is separated by a line \
break. +    loadCellText(cell, element, tableContext, autoStyles, cellStyleName);
+
+    //
+    // formula
+    //
+    bool isFormula = false;
+    if (element.hasAttributeNS(KoXmlNS::table, sFormula)) {
+        isFormula = true;
+        QString oasisFormula(element.attributeNS(KoXmlNS::table, sFormula, \
QString())); +        // debugSheetsODF << "cell:" << name() << "formula :" << \
oasisFormula; +        // each spreadsheet application likes to safe formulas with a \
different namespace +        // prefix, so remove all of them
+        QString namespacePrefix;
+        foreach(const QString &prefix, formulaNSPrefixes) {
+            if (oasisFormula.startsWith(prefix)) {
+                oasisFormula.remove(0, prefix.length());
+                namespacePrefix = prefix;
+                break;
+            }
+        }
+        oasisFormula = Odf::decodeFormula(oasisFormula, locale(), namespacePrefix);
+        cell->setUserInput(oasisFormula);
+    } else if (!userInput().isEmpty() && userInput().at(0) == '=')  //prepend ' to \
the text to avoid = to be painted +        \
cell->setUserInput(userInput().prepend('\'')); +
+    //
+    // validation
+    //
+    if (element.hasAttributeNS(KoXmlNS::table, sValidationName)) {
+        const QString validationName = element.attributeNS(KoXmlNS::table, \
sValidationName, QString()); +        debugSheetsODF << "cell:" << name() << \
sValidationName << validationName; +        Validity validity;
+#warning use new odf
+        validity.loadOdfValidation(this, validationName, tableContext);
+        if (!validity.isEmpty())
+            setValidity(validity);
+    }
+
+    //
+    // value type
+    //
+    if (element.hasAttributeNS(KoXmlNS::office, sValueType)) {
+        const QString valuetype = element.attributeNS(KoXmlNS::office, sValueType, \
QString()); +        // debugSheetsODF << "cell:" << name() << "value-type:" << \
valuetype; +        if (valuetype == sBoolean) {
+            const QString val = element.attributeNS(KoXmlNS::office, sBooleanValue, \
QString()).toLower(); +            if ((val == sTrue) || (val == sFalse))
+                cell->setValue(Value(val == sTrue));
+        }
+
+        // integer and floating-point value
+        else if (valuetype == sFloat) {
+            bool ok = false;
+            Value value(element.attributeNS(KoXmlNS::office, sValue, \
QString()).toDouble(&ok)); +            if (ok) {
+                value.setFormat(Value::fmt_Number);
+                cell->setValue(value);
+#if 0
+                Style style;
+                style.setFormatType(Format::Number);
+                cell->setStyle(style);
+#endif
+            }
+            // always set the userInput to the actual value read from the cell, and \
not whatever happens to be set as text, as the textual representation of a value may \
be less accurate than the value itself +            if (!isFormula)
+                cell->setUserInput(cell->sheet()->map()->converter()->asString(value).asString());
 +        }
+
+        // currency value
+        else if (valuetype == sCurrency) {
+            bool ok = false;
+            Value value(element.attributeNS(KoXmlNS::office, sValue, \
QString()).toDouble(&ok)); +            if (ok) {
+                value.setFormat(Value::fmt_Money);
+                cell->setValue(value);
+
+                Currency currency;
+                if (element.hasAttributeNS(KoXmlNS::office, sCurrency)) {
+                    currency = Currency(element.attributeNS(KoXmlNS::office, \
sCurrency, QString())); +                }
+                /* TODO: somehow make this work again, all setStyle calls here will \
be overwritten by cell styles later +                if( style.isEmpty() ) {
+                    Style style;
+                    style.setCurrency(currency);
+                    setStyle(style);
+                } */
+            }
+        } else if (valuetype == sPercentage) {
+            bool ok = false;
+            Value value(element.attributeNS(KoXmlNS::office, sValue, \
QString()).toDouble(&ok)); +            if (ok) {
+                value.setFormat(Value::fmt_Percent);
+                cell->setValue(value);
+                if (!isFormula && cell->userInput().isEmpty())
+                    \
cell->setUserInput(cell->sheet()->map()->converter()->asString(value).asString()); \
+// FIXME Stefan: Should be handled by Value::Format. Verify and remove! +#if 0
+                Style style;
+                style.setFormatType(Format::Percentage);
+                setStyle(style);
+#endif
+            }
+        } else if (valuetype == sDate) {
+            QString value = element.attributeNS(KoXmlNS::office, sDateValue, \
QString()); +
+            // "1980-10-15" or "2001-01-01T19:27:41"
+            int year = 0, month = 0, day = 0, hours = 0, minutes = 0, seconds = 0;
+            bool hasTime = false;
+            bool ok = false;
+
+            int p1 = value.indexOf('-');
+            if (p1 > 0) {
+                year  = value.left(p1).toInt(&ok);
+                if (ok) {
+                    int p2 = value.indexOf('-', ++p1);
+                    month = value.mid(p1, p2 - p1).toInt(&ok);
+                    if (ok) {
+                        // the date can optionally have a time attached
+                        int p3 = value.indexOf('T', ++p2);
+                        if (p3 > 0) {
+                            hasTime = true;
+                            day = value.mid(p2, p3 - p2).toInt(&ok);
+                            if (ok) {
+                                int p4 = value.indexOf(':', ++p3);
+                                hours = value.mid(p3, p4 - p3).toInt(&ok);
+                                if (ok) {
+                                    int p5 = value.indexOf(':', ++p4);
+                                    minutes = value.mid(p4, p5 - p4).toInt(&ok);
+                                    if (ok)
+                                        seconds = value.right(value.length() - p5 - \
1).toInt(&ok); +                                }
+                            }
+                        } else {
+                            day = value.right(value.length() - p2).toInt(&ok);
+                        }
+                    }
+                }
+            }
+
+            if (ok) {
+                if (hasTime)
+                    cell->setValue(Value(QDateTime(QDate(year, month, day), \
QTime(hours, minutes, seconds)), cell->sheet()->map()->calculationSettings())); +     \
else +                    cell->setValue(Value(QDate(year, month, day), \
cell->sheet()->map()->calculationSettings())); +// FIXME Stefan: Should be handled by \
Value::Format. Verify and remove! +//Sebsauer: Fixed now. Value::Format handles it \
correct. +#if 0
+                Style s;
+                s.setFormatType(Format::ShortDate);
+                setStyle(s);
+#endif
+                // debugSheetsODF << "cell:" << name() << "Type: date, value:" << \
value << "Date:" << year << " -" << month << " -" << day; +            }
+        } else if (valuetype == sTime) {
+            QString value = element.attributeNS(KoXmlNS::office, sTimeValue, \
QString()); +
+            // "PT15H10M12S"
+            int hours = 0, minutes = 0, seconds = 0;
+            int l = value.length();
+            QString num;
+            bool ok = false;
+            for (int i = 0; i < l; ++i) {
+                if (value[i].isNumber()) {
+                    num += value[i];
+                    continue;
+                } else if (value[i] == 'H')
+                    hours   = num.toInt(&ok);
+                else if (value[i] == 'M')
+                    minutes = num.toInt(&ok);
+                else if (value[i] == 'S')
+                    seconds = num.toInt(&ok);
+                else
+                    continue;
+                //debugSheetsODF << "Num:" << num;
+                num.clear();
+                if (!ok)
+                    break;
+            }
+
+            if (ok) {
+                // Value kval( timeToNum( hours, minutes, seconds ) );
+                // cell->setValue( kval );
+                cell->setValue(Value(QTime(hours % 24, minutes, seconds)));
+// FIXME Stefan: Should be handled by Value::Format. Verify and remove!
+#if 0
+                Style style;
+                style.setFormatType(Format::Time);
+                setStyle(style);
+#endif
+                // debugSheetsODF << "cell:" << name() << "Type: time:" << value << \
"Hours:" << hours << "," << minutes << "," << seconds; +            }
+        } else if (valuetype == sString) {
+            if (element.hasAttributeNS(KoXmlNS::office, sStringValue)) {
+                QString value = element.attributeNS(KoXmlNS::office, sStringValue, \
QString()); +                cell->setValue(Value(value));
+            } else {
+                // use the paragraph(s) read in before
+                cell->setValue(Value(cell->userInput()));
+            }
+// FIXME Stefan: Should be handled by Value::Format. Verify and remove!
+#if 0
+            Style style;
+            style.setFormatType(Format::Text);
+            setStyle(style);
+#endif
+        } else {
+            // debugSheetsODF << "cell:" << name() << "  Unknown type. Parsing user \
input."; +            // Set the value by parsing the user input.
+            cell->parseUserInput(cell->userInput());
+        }
+    } else { // no value-type attribute
+        // debugSheetsODF << "cell:" << name() << "  No value type specified. \
Parsing user input."; +        // Set the value by parsing the user input.
+        cell->parseUserInput(cell->userInput());
+    }
+
+    //
+    // merged cells ?
+    //
+    int colSpan = 1;
+    int rowSpan = 1;
+    if (element.hasAttributeNS(KoXmlNS::table, sNumberColumnsSpanned)) {
+        bool ok = false;
+        int span = element.attributeNS(KoXmlNS::table, sNumberColumnsSpanned, \
QString()).toInt(&ok); +        if (ok) colSpan = span;
+    }
+    if (element.hasAttributeNS(KoXmlNS::table, sNumberRowsSpanned)) {
+        bool ok = false;
+        int span = element.attributeNS(KoXmlNS::table, sNumberRowsSpanned, \
QString()).toInt(&ok); +        if (ok) rowSpan = span;
+    }
+    if (colSpan > 1 || rowSpan > 1)
+        mergeCells(d->column, d->row, colSpan - 1, rowSpan - 1);
+
+    //
+    // cell comment/annotation
+    //
+    KoXmlElement annotationElement = KoXml::namedItemNS(element, KoXmlNS::office, \
sAnnotation); +    if (!annotationElement.isNull()) {
+        QString comment;
+        KoXmlNode node = annotationElement.firstChild();
+        while (!node.isNull()) {
+            KoXmlElement commentElement = node.toElement();
+            if (!commentElement.isNull())
+                if (commentElement.localName() == sP && \
commentElement.namespaceURI() == KoXmlNS::text) { +                    if \
(!comment.isEmpty()) comment.append('\n'); +                    \
comment.append(commentElement.text()); +                }
+
+            node = node.nextSibling();
+        }
+        if (!comment.isEmpty())
+            setComment(comment);
+    }
+
+    loadObjects(cell, element, tableContext, shapeData);
+
+    return true;
+}
+
+bool Odf::saveCell(Cell *cell, int &repeated, OdfSavingContext& tableContext)
+{
+    KoXmlWriter & xmlwriter = tableContext.shapeContext.xmlWriter();
+    KoGenStyles & mainStyles = tableContext.shapeContext.mainStyles();
+
+    int row = cell->row();
+    int column = cell->column();
+
+    // see: OpenDocument, 8.1.3 Table Cell
+    if (!isPartOfMerged())
+        xmlwriter.startElement("table:table-cell");
+    else
+        xmlwriter.startElement("table:covered-table-cell");
+#if 0
+    //add font style
+    QFont font;
+    Value const value(cell.value());
+    if (!cell.isDefault()) {
+        font = cell.format()->textFont(i, row);
+        m_styles.addFont(font);
+
+        if (cell.format()->hasProperty(Style::SComment))
+            hasComment = true;
+    }
+#endif
+    // NOTE save the value before the style as long as the Formatter does not work \
correctly +    if (cell->link().isEmpty())
+        saveCellValue(cell, xmlwriter);
+
+    const Style cellStyle = cell->style();
+
+    // Either there's no column and row default and the style's not the default \
style, +    // or the style is different to one of them. The row default takes \
precedence. +    if ((!tableContext.rowDefaultStyles.contains(row) &&
+            !tableContext.columnDefaultStyles.contains(column) &&
+            !(cellStyle.isDefault() && conditions().isEmpty())) ||
+            (tableContext.rowDefaultStyles.contains(row) && \
tableContext.rowDefaultStyles[row] != cellStyle) || +            \
(tableContext.columnDefaultStyles.contains(column) && \
tableContext.columnDefaultStyles[column] != cellStyle)) { +        KoGenStyle \
currentCellStyle; // the type determined in saveCellStyle +        QString styleName \
= saveCellStyle(currentCellStyle, mainStyles); +        // skip 'table:style-name' \
attribute for the default style +        if (!currentCellStyle.isDefaultStyle()) {
+            if (!styleName.isEmpty())
+                xmlwriter.addAttribute("table:style-name", styleName);
+        }
+    }
+
+    // group empty cells with the same style
+    const QString comment = cell->comment();
+    if (isEmpty() && comment.isEmpty() && !isPartOfMerged() && !doesMergeCells() &&
+            !tableContext.cellHasAnchoredShapes(cell->sheet(), row, column)) {
+        bool refCellIsDefault = isDefault();
+        int j = column + 1;
+        Cell nextCell = cell->sheet()->cellStorage()->nextInRow(column, row);
+        while (!nextCell.isNull()) {
+            // if
+            //   the next cell is not the adjacent one
+            // or
+            //   the next cell is not empty
+            if (nextCell.column() != j || (!nextCell.isEmpty() || \
tableContext.cellHasAnchoredShapes(cell->sheet(), row, column))) { +                \
if (refCellIsDefault) { +                    // if the origin cell was a default \
cell, +                    // we count the default cells
+                    repeated = nextCell.column() - j + 1;
+
+                    // check if any of the empty/default cells we skipped contained \
anchored shapes +                    int shapeColumn = \
tableContext.nextAnchoredShape(cell->sheet(), row, column); +                    if \
(shapeColumn) { +                        repeated = qMin(repeated, shapeColumn - \
column); +                    }
+                }
+                // otherwise we just stop here to process the adjacent
+                // cell in the next iteration of the outer loop
+                // (in saveCells)
+                break;
+            }
+
+            if (nextCell.isPartOfMerged() || nextCell.doesMergeCells() ||
+                    !nextCell.comment().isEmpty() || \
tableContext.cellHasAnchoredShapes(cell->sheet(), row, nextCell.column()) || +        \
!(nextCell.style() == cellStyle && nextCell.conditions() == conditions())) { +        \
break; +            }
+            ++repeated;
+            // get the next cell and set the index to the adjacent cell
+            nextCell = cell->sheet()->cellStorage()->nextInRow(j++, row);
+        }
+        //debugSheetsODF << "Odf::saveCell: empty cell in column" << column
+        //<< "repeated" << repeated << "time(s)" << endl;
+
+        if (repeated > 1)
+            xmlwriter.addAttribute("table:number-columns-repeated", \
QString::number(repeated)); +    }
+
+    Validity validity = cell->validity();
+    if (!validity.isEmpty()) {
+        GenValidationStyle styleVal(&validity, cell->sheet()->map()->converter());
+        xmlwriter.addAttribute("table:validation-name", \
tableContext.valStyle.insert(styleVal)); +    }
+    if (cell->isFormula()) {
+        //debugSheetsODF <<"Formula found";
+        QString formula = Odf::encodeFormula(userInput(), locale());
+        xmlwriter.addAttribute("table:formula", formula);
+    }
+
+    if (doesMergeCells()) {
+        int colSpan = mergedXCells() + 1;
+        int rowSpan = mergedYCells() + 1;
+
+        if (colSpan > 1)
+            xmlwriter.addAttribute("table:number-columns-spanned", \
QString::number(colSpan)); +
+        if (rowSpan > 1)
+            xmlwriter.addAttribute("table:number-rows-spanned", \
QString::number(rowSpan)); +    }
+
+    saveCellAnnotation(cell, xmlwriter);
+
+    if (!cell->isFormula() && !link().isEmpty()) {
+        //debugSheetsODF<<"Link found";
+        xmlwriter.startElement("text:p");
+        xmlwriter.startElement("text:a");
+        const QString url = link();
+        //Reference cell is started by '#'
+        if (Util::localReferenceAnchor(url))
+            xmlwriter.addAttribute("xlink:href", ('#' + url));
+        else
+            xmlwriter.addAttribute("xlink:href", url);
+        xmlwriter.addAttribute("xlink:type", "simple");
+        xmlwriter.addTextNode(userInput());
+        xmlwriter.endElement();
+        xmlwriter.endElement();
+    }
+
+    if (!isEmpty() && link().isEmpty()) {
+        QSharedPointer<QTextDocument> doc = richText();
+        if (doc) {
+            QTextCharFormat format = style().asCharFormat();
+            ((KoCharacterStyle \
*)cell->sheet()->map()->textStyleManager()->defaultParagraphStyle())->copyProperties(format);
 +
+            KoTextWriter writer(tableContext.shapeContext);
+
+            writer.write(doc.data(), 0);
+        } else {
+            xmlwriter.startElement("text:p");
+            xmlwriter.addTextNode(displayText().toUtf8());
+            xmlwriter.endElement();
+        }
+    }
+
+    // flake
+    // Save shapes that are anchored to this cell.
+    // see: OpenDocument, 2.3.1 Text Documents
+    // see: OpenDocument, 9.2 Drawing Shapes
+    if (tableContext.cellHasAnchoredShapes(cell->sheet(), row, column)) {
+        const QList<KoShape*> shapes = \
tableContext.cellAnchoredShapes(cell->sheet(), row, column); +        for (int i = 0; \
i < shapes.count(); ++i) { +            KoShape* const shape = shapes[i];
+            const QPointF bottomRight = shape->boundingRect().bottomRight();
+            qreal endX = 0.0;
+            qreal endY = 0.0;
+            const int scol = cell->sheet()->leftColumn(bottomRight.x(), endX);
+            const int srow = cell->sheet()->topRow(bottomRight.y(), endY);
+            qreal offsetX = cell->sheet()->columnPosition(column);
+            qreal offsetY = cell->sheet()->rowPosition(row);
+            tableContext.shapeContext.addShapeOffset(shape, \
QTransform::fromTranslate(-offsetX, -offsetY)); +#warning use new odf
+            shape->setAdditionalAttribute("table:end-cell-address", \
Region(QPoint(scol, srow)).saveOdf()); +            \
shape->setAdditionalAttribute("table:end-x", QString::number(bottomRight.x() - endX) \
+ "pt"); +            shape->setAdditionalAttribute("table:end-y", \
QString::number(bottomRight.y() - endY) + "pt"); +            \
shape->saveOdf(tableContext.shapeContext); +            \
shape->removeAdditionalAttribute("table:end-cell-address"); +            \
shape->removeAdditionalAttribute("table:end-x"); +            \
shape->removeAdditionalAttribute("table:end-y"); +            \
tableContext.shapeContext.removeShapeOffset(shape); +        }
+    }
+
+    xmlwriter.endElement();
+    return true;
+}
+
+
+// loading - helper functions
+
+QString Odf::loadCellTextNodes(Cell *cell, const KoXmlElement& element, int \
*textFragmentCount, int *lineCount, bool *hasRichText, bool *stripLeadingSpace) +{
+    QString cellText;
+    bool countedOwnFragments = false;
+    bool prevWasText = false;
+    for (KoXmlNode n = element.firstChild(); !n.isNull(); n = n.nextSibling()) {
+        if (n.isText()) {
+            prevWasText = true;
+            QString t = KoTextLoader::normalizeWhitespace(n.toText().data(), \
*stripLeadingSpace); +            if (!t.isEmpty()) {
+                *stripLeadingSpace = t[t.length() - 1].isSpace();
+                cellText += t;
+                if (!countedOwnFragments) {
+                    // We only count the number of different parent elements which \
have text. That is +                    // so cause different parent-elements may \
mean different styles which means +                    // rich-text while the same \
parent element means the same style so we can easily +                    // put them \
together into one string. +                    countedOwnFragments = true;
+                    ++(*textFragmentCount);
+                }
+            }
+        } else {
+            KoXmlElement e = n.toElement();
+            if (!e.isNull()) {
+                if (prevWasText && !cellText.isEmpty() && cellText[cellText.length() \
- 1].isSpace()) { +                    // A trailing space of the cellText collected \
so far needs to be preserved when +                    // more text-nodes within the \
same parent follow but if an element like e.g. +                    // text:s follows \
then a trailing space needs to be removed. +                    cellText.chop(1);
+                }
+                prevWasText = false;
+
+                // We can optimize some elements like text:s (space), text:tab \
(tabulator) and +                // text:line-break (new-line) to not produce \
rich-text but add the equivalent +                // for them in plain-text.
+                const bool isTextNs = e.namespaceURI() == KoXmlNS::text;
+                if (isTextNs && e.localName() == "s") {
+                    const int howmany = qMax(1, e.attributeNS(KoXmlNS::text, "c", \
QString()).toInt()); +                    cellText += QString().fill(32, howmany);
+                } else if (isTextNs && e.localName() == "tab") {
+                    cellText += '\t';
+                } else if (isTextNs && e.localName() == "line-break") {
+                    cellText += '\n';
+                    ++(*lineCount);
+                } else if (isTextNs && e.localName() == "span") {
+                    // Nested span-elements means recursive evaluation.
+                    cellText += loadCellTextNodes(cell, e, textFragmentCount, \
lineCount, hasRichText, stripLeadingSpace); +                } else if (!isTextNs ||
+                              ( e.localName() != "annotation" &&
+                                e.localName() != "bookmark" &&
+                                e.localName() != "meta" &&
+                                e.localName() != "tag" )) {
+                    // Seems we have an element we cannot easily translate to a \
string what +                    // means it's all rich-text now.
+                    *hasRichText = true;
+                }
+            }
+        }
+    }
+    return cellText;
+}
+
+// recursively goes through all children of parent and returns true if there is any \
element +// in the draw: namespace in this subtree
+static bool findDrawElements(const KoXmlElement& parent)
+{
+    KoXmlElement element;
+    forEachElement(element , parent) {
+        if (element.namespaceURI() == KoXmlNS::draw)
+            return true;
+        if (findDrawElements(element))
+            return true;
+    }
+    return false;
+}
+
+// Similar to KoXml::namedItemNS except that children of span tags will be evaluated \
too. +static KoXmlElement namedItemNSWithSpan(const KoXmlNode& node, const QString \
&nsURI, const QString &localName) +{
+    KoXmlNode n = node.firstChild();
+    for (; !n.isNull(); n = n.nextSibling()) {
+        if (n.isElement()) {
+            if (n.localName() == localName && n.namespaceURI() == nsURI) {
+                return n.toElement();
+            }
+            if (n.localName() == "span" && n.namespaceURI() == nsURI) {
+                KoXmlElement e = KoXml::namedItemNS(n, nsURI, localName); // not \
recursive +                if (!e.isNull()) {
+                    return e;
+                }
+            }
+        }
+    }
+    return KoXmlElement();
+}
+
+void Odf::loadCellText(Cell *cell, const KoXmlElement& parent, OdfLoadingContext& \
tableContext, const Styles& autoStyles, const QString& cellStyleName) +{
+    //Search and load each paragraph of text. Each paragraph is separated by a line \
break +    KoXmlElement textParagraphElement;
+    QString cellText;
+
+    int lineCount = 0;
+    bool hasRichText = false;
+    bool stripLeadingSpace = true;
+
+    forEachElement(textParagraphElement , parent) {
+        if (textParagraphElement.localName() == "p" &&
+                textParagraphElement.namespaceURI() == KoXmlNS::text) {
+
+            // the text:a link could be located within a text:span element
+            KoXmlElement textA = namedItemNSWithSpan(textParagraphElement, \
KoXmlNS::text, "a"); +            if (!textA.isNull() && \
textA.hasAttributeNS(KoXmlNS::xlink, "href")) { +                QString link = \
textA.attributeNS(KoXmlNS::xlink, "href", QString()); +                cellText = \
textA.text(); +                cell->setUserInput(cellText);
+                hasRichText = false;
+                lineCount = 0;
+                // The value will be set later in loadOdf().
+                if ((!link.isEmpty()) && (link[0] == '#'))
+                    link.remove(0, 1);
+                cell->setLink(link);
+                // Abort here cause we can handle only either a link in a cell or \
(rich-)text but not both. +                break;
+            }
+
+            if (!cellText.isNull())
+                cellText += '\n';
+
+            ++lineCount;
+            int textFragmentCount = 0;
+
+            // Our text could contain formating for value or result of formula or a \
mix of +            // multiple text:span elements with text-nodes and line-break's.
+            cellText += loadCellTextNodes(cell, textParagraphElement, \
&textFragmentCount, &lineCount, &hasRichText, &stripLeadingSpace); +
+            // If we got text from multiple different sources (e.g. from the text:p \
and a +            // child text:span) then we have very likely rich-text.
+            if (!hasRichText)
+                hasRichText = textFragmentCount >= 2;
+        }
+    }
+
+    if (!cellText.isNull()) {
+        if (hasRichText && !findDrawElements(parent)) {
+            // for now we don't support richtext and embedded shapes in the same \
cell; +            // this is because they would currently be loaded twice, once by \
the KoTextLoader +            // and later properly by the cell itself
+
+            Style style; style.setDefault();
+            if (!cellStyleName.isEmpty()) {
+                if (autoStyles.contains(cellStyleName))
+                    style.merge(autoStyles[cellStyleName]);
+                else {
+                    const CustomStyle* namedStyle = \
cell->sheet()->map()->styleManager()->style(cellStyleName); +                    if \
(namedStyle) +                        style.merge(*namedStyle);
+                }
+            }
+
+            QTextCharFormat format = style.asCharFormat();
+            ((KoCharacterStyle \
*)cell->sheet()->map()->textStyleManager()->defaultParagraphStyle())->copyProperties(format);
 +
+            QSharedPointer<QTextDocument> doc(new QTextDocument);
+            KoTextDocument(doc.data()).setStyleManager(cell->sheet()->map()->textStyleManager());
 +
+            Q_ASSERT(tableContext.shapeContext);
+            KoTextLoader loader(*tableContext.shapeContext);
+            QTextCursor cursor(doc.data());
+            loader.loadBody(parent, cursor);
+
+            cell->setUserInput(doc->toPlainText());
+            cell->setRichText(doc);
+        } else {
+            cell->setUserInput(cellText);
+        }
+    }
+
+    // enable word wrapping if multiple lines of text have been found.
+    if (lineCount >= 2) {
+        Style newStyle;
+        newStyle.setWrapText(true);
+        setStyle(newStyle);
+    }
+}
+
+void Odf::loadObjects(Cell *cell, const KoXmlElement &parent, OdfLoadingContext& \
tableContext, QList<ShapeLoadingData>& shapeData) +{
+    // Register additional attributes, that identify shapes anchored in cells.
+    // Their dimensions need adjustment after all rows are loaded,
+    // because the position of the end cell is not always known yet.
+    KoShapeLoadingContext::addAdditionalAttributeData(KoShapeLoadingContext::AdditionalAttributeData(
 +                KoXmlNS::table, "end-cell-address",
+                "table:end-cell-address"));
+    KoShapeLoadingContext::addAdditionalAttributeData(KoShapeLoadingContext::AdditionalAttributeData(
 +                KoXmlNS::table, "end-x",
+                "table:end-x"));
+    KoShapeLoadingContext::addAdditionalAttributeData(KoShapeLoadingContext::AdditionalAttributeData(
 +                KoXmlNS::table, "end-y",
+                "table:end-y"));
+
+    KoXmlElement element;
+    forEachElement(element, parent) {
+        if (element.namespaceURI() != KoXmlNS::draw)
+            continue;
+
+        if (element.localName() == "a") {
+            // It may the case that the object(s) are embedded into a hyperlink so \
actions are done on +            // clicking it/them but since we do not supported \
objects-with-hyperlinks yet we just fetch +            // the inner elements and use \
them to at least create and show the objects (see bug 249862). +            \
KoXmlElement e; +            forEachElement(e, element) {
+                if (e.namespaceURI() != KoXmlNS::draw)
+                    continue;
+                ShapeLoadingData data = loadObject(cell, e, \
*tableContext.shapeContext); +                if (data.shape) {
+                    shapeData.append(data);
+                }
+            }
+        } else {
+            ShapeLoadingData data = loadObject(cell, element, \
*tableContext.shapeContext); +            if (data.shape) {
+                shapeData.append(data);
+            }
+        }
+    }
+}
+
+ShapeLoadingData Odf::loadObject(Cell *cell, const KoXmlElement &element, \
KoShapeLoadingContext &shapeContext) +{
+    ShapeLoadingData data;
+    data.shape = 0;
+    KoShape* shape = KoShapeRegistry::instance()->createShapeFromOdf(element, \
shapeContext); +    if (!shape) {
+        debugSheetsODF << "Unable to load shape with localName=" << \
element.localName(); +        return data;
+    }
+
+    cell->sheet()->addShape(shape);
+
+    // The position is relative to the upper left sheet corner until now. Move it.
+    QPointF position = shape->position();
+    // Remember how far we're off from the top-left corner of this cell
+    double offsetX = position.x();
+    double offsetY = position.y();
+    for (int col = 1; col < column(); ++col)
+        position += QPointF(cell->sheet()->columnFormat(col)->width(), 0.0);
+    if (cell->row() > 1)
+        position += QPointF(0.0, cell->sheet()->rowFormats()->totalRowHeight(1, \
cell->row() - 1)); +    shape->setPosition(position);
+
+    dynamic_cast<ShapeApplicationData*>(shape->applicationData())->setAnchoredToCell(true);
 +
+    // All three attributes are necessary for cell anchored shapes.
+    // Otherwise, they are anchored in the sheet.
+    if (!shape->hasAdditionalAttribute("table:end-cell-address") ||
+            !shape->hasAdditionalAttribute("table:end-x") ||
+            !shape->hasAdditionalAttribute("table:end-y")) {
+        debugSheetsODF << "Not all attributes found, that are necessary for cell \
anchoring."; +        return data;
+    }
+
+#warning use new odf
+    Region endCell(Region::loadOdf(shape->additionalAttribute("table:end-cell-address")),
 +                   cell->sheet()->map(), cell->sheet());
+    if (!endCell.isValid() || !endCell.isSingular())
+        return data;
+
+    QString string = shape->additionalAttribute("table:end-x");
+    if (string.isNull())
+        return data;
+    double endX = KoUnit::parseValue(string);
+
+    string = shape->additionalAttribute("table:end-y");
+    if (string.isNull())
+        return data;
+    double endY = KoUnit::parseValue(string);
+
+    data.shape = shape;
+    data.startCell = QPoint(column(), row());
+    data.offset = QPointF(offsetX, offsetY);
+    data.endCell = endCell;
+    data.endPoint = QPointF(endX, endY);
+
+    // The column dimensions are already the final ones, but not the row dimensions.
+    // The default height is used for the not yet loaded rows.
+    // TODO Stefan: Honor non-default row heights later!
+    // subtract offset because the accumulated width and height we calculate below \
starts +    // at the top-left corner of this cell, but the shape can have an offset \
to that corner +    QSizeF size = QSizeF(endX - offsetX, endY - offsetY);
+    for (int col = column(); col < endCell.firstRange().left(); ++col)
+        size += QSizeF(cell->sheet()->columnFormat(col)->width(), 0.0);
+    if (endCell.firstRange().top() > cell->row())
+        size += QSizeF(0.0, cell->sheet()->rowFormats()->totalRowHeight(cell->row(), \
endCell.firstRange().top() - 1)); +    shape->setSize(size);
+
+    return data;
+}
+
+
+// saving - helper functions
+
+void Odf::saveCellAnnotation(Cell *cell, KoXmlWriter &xmlwriter)
+{
+    const QString comment = cell->comment();
+    if (comment.isEmpty()) return;
+
+    //<office:annotation draw:style-name="gr1" draw:text-style-name="P1" \
svg:width="2.899cm" svg:height="2.691cm" svg:x="2.858cm" svg:y="0.001cm" \
draw:caption-point-x="-2.858cm" draw:caption-point-y="-0.001cm"> +    \
xmlwriter.startElement("office:annotation"); +    const QStringList text = \
comment.split('\n', QString::SkipEmptyParts); +    for (QStringList::ConstIterator it \
= text.begin(); it != text.end(); ++it) { +        xmlwriter.startElement("text:p");
+        xmlwriter.addTextNode(*it);
+        xmlwriter.endElement();
+    }
+    xmlwriter.endElement();
+}
+
+
+QString Odf::saveCellStyle(Cell *cell, KoGenStyle &currentCellStyle, KoGenStyles \
&mainStyles) +{
+    const Conditions conditions = cell->conditions();
+    if (!conditions.isEmpty()) {
+        // this has to be an automatic style
+        currentCellStyle = KoGenStyle(KoGenStyle::TableCellAutoStyle, "table-cell");
+#warning use new odf
+        conditions.saveOdfConditions(currentCellStyle, \
cell->sheet()->map()->converter()); +    }
+#warning TODO new style odf
+    return style().saveOdf(currentCellStyle, mainStyles, \
cell->sheet()->map()->styleManager()); +}
+
+void Odf::saveCellValue(Cell *cell, KoXmlWriter &xmlWriter)
+{
+    Value value = cell->value();
+    // Determine the format that we will be storing.
+    // This is usually the format that is actually shown - doing so mixes style and \
content, but that's how +    // LO does it, so we need to stay compatible
+    Format::Type shownFormat = style().formatType();
+    if (shownFormat == Format::Generic)
+        shownFormat = cell->sheet()->map()->formatter()->determineFormatting(value, \
shownFormat); +    Value::Format saveFormat = Value::fmt_None;
+    Value::Format valueFormat = value.format();
+    if (valueFormat == Value::fmt_Boolean)
+        saveFormat = Value::fmt_Boolean;
+    else if (valueFormat == Value::fmt_String)  // if it's a text, it needs to be \
stored as a text +        saveFormat = Value::fmt_String;
+    else if (Format::isDate(shownFormat))
+        saveFormat = Value::fmt_Date;
+    else if (Format::isTime(shownFormat))
+        saveFormat = Value::fmt_Time;
+    else if (Format::isNumber(shownFormat))
+        saveFormat = Value::fmt_Number;
+    else if (Format::isMoney(shownFormat))
+        saveFormat = Value::fmt_Money;
+    else if (shownFormat == Format::Percentage)
+        saveFormat = Value::fmt_Percent;
+    else if (shownFormat == Format::Text)
+        saveFormat = Value::fmt_String;
+    else if (shownFormat == Format::Custom)
+        saveFormat = valueFormat;
+
+    switch (saveFormat) {
+    case Value::fmt_None: break;  //NOTHING HERE
+    case Value::fmt_Boolean: {
+        xmlWriter.addAttribute("office:value-type", "boolean");
+        xmlWriter.addAttribute("office:boolean-value", (value.asBoolean() ? "true" : \
"false")); +        break;
+    }
+    case Value::fmt_Number: {
+        xmlWriter.addAttribute("office:value-type", "float");
+        if (value.isInteger())
+            xmlWriter.addAttribute("office:value", \
QString::number(value.asInteger())); +        else
+            xmlWriter.addAttribute("office:value", \
QString::number(numToDouble(value.asFloat()), 'g', DBL_DIG)); +        break;
+    }
+    case Value::fmt_Percent: {
+        xmlWriter.addAttribute("office:value-type", "percentage");
+        xmlWriter.addAttribute("office:value", QString::number((double) \
numToDouble(value.asFloat()))); +        break;
+    }
+    case Value::fmt_Money: {
+        xmlWriter.addAttribute("office:value-type", "currency");
+        const Style style = cell->style();
+        if (style.hasAttribute(Style::CurrencyFormat)) {
+            Currency currency = style.currency();
+            xmlWriter.addAttribute("office:currency", currency.code());
+        }
+        xmlWriter.addAttribute("office:value", QString::number((double) \
numToDouble(value.asFloat()))); +        break;
+    }
+    case Value::fmt_DateTime: break;  //NOTHING HERE
+    case Value::fmt_Date: {
+        xmlWriter.addAttribute("office:value-type", "date");
+        xmlWriter.addAttribute("office:date-value",
+                               \
value.asDate(cell->sheet()->map()->calculationSettings()).toString(Qt::ISODate)); +   \
break; +    }
+    case Value::fmt_Time: {
+        xmlWriter.addAttribute("office:value-type", "time");
+        xmlWriter.addAttribute("office:time-value",
+                               value.asTime().toString("'PT'hh'H'mm'M'ss'S'"));
+        break;
+    }
+    case Value::fmt_String: {
+        xmlWriter.addAttribute("office:value-type", "string");
+        xmlWriter.addAttribute("office:string-value", value.asString());
+        break;
+    }
+    };
+}
+
+
+
+
 
 }  // Sheets
 }  // Calligra
diff --git a/sheets/odf/SheetsOdfSheet.cpp b/sheets/odf/SheetsOdfSheet.cpp
index f43758b..5254bf6 100644
--- a/sheets/odf/SheetsOdfSheet.cpp
+++ b/sheets/odf/SheetsOdfSheet.cpp
@@ -74,6 +74,8 @@
 namespace Calligra {
 namespace Sheets {
 
+class Cell;
+
 template<typename T> class IntervalMap
 {
 public:
@@ -96,7 +98,11 @@ private:
 
 
 namespace Odf {
+    // Sheet loading and saving
     bool loadSheet(Sheet *sheet, const KoXmlElement& sheetElement, \
OdfLoadingContext& tableContext, const Styles& autoStyles, const QHash<QString, \
Conditions>& conditionalStyles); +    bool saveSheet(Sheet *sheet, OdfSavingContext& \
tableContext); +
+    // Sheet loading - helper functions
     /**
      * Inserts the styles contained in \p styleRegions into the style storage.
      * Looks automatic styles up in the map of preloaded automatic styles,
@@ -140,7 +146,7 @@ namespace Odf {
     QString getPart(const KoXmlNode & part);
     void replaceMacro(QString & text, const QString & old, const QString & newS);
 
-    bool saveSheet(Sheet *sheet, OdfSavingContext& tableContext);
+    // Sheet saving - helper functions
     QString saveSheetStyleName(Sheet *sheet, KoGenStyles &mainStyles);
     void saveColRowCell(Sheet *sheet, int maxCols, int maxRows, OdfSavingContext& \
                tableContext);
     void saveCells(Sheet *sheet, int row, int maxCols, OdfSavingContext& \
tableContext); @@ -150,8 +156,15 @@ namespace Odf {
     void convertPart(Sheet *sheet, const QString & part, KoXmlWriter & xmlWriter);
     bool compareRows(Sheet *sheet, int row1, int row2, int maxCols, \
OdfSavingContext& tableContext);  
+    // sheet settings
     void loadSheetSettings(Sheet *sheet, const KoOasisSettings::NamedMap &settings);
     void saveSheetSettings(Sheet *sheet, KoXmlWriter &settingsWriter);
+
+    // Cell loading - in SheetsOdfCell
+    bool loadCell(Cell *cell, const KoXmlElement& element, OdfLoadingContext& \
tableContext, +            const Styles& autoStyles, const QString& cellStyleName,
+            QList<ShapeLoadingData>& shapeData);
+    bool saveCell(Cell *cell, int &repeated, OdfSavingContext& tableContext);
 }
 
 // *************** Loading *****************
@@ -980,8 +993,7 @@ int Odf::loadRowFormat(Sheet *sheet, const KoXmlElement& row, int \
&rowIndex,  cellStyleName = columnStyles.get(columnIndex);
 
         Cell cell(sheet, columnIndex, rowIndex);
-#warning TODO new style odf
-        cell.loadOdf(cellElement, tableContext, autoStyles, cellStyleName, \
shapeData); +        loadCell(&cell, cellElement, tableContext, autoStyles, \
cellStyleName, shapeData);  
         if (!cell.comment().isEmpty())
             sheet->cellStorage()->setComment(Region(columnIndex, rowIndex, \
numberColumns, number, sheet), cell.comment()); @@ -1287,7 +1299,7 @@ void \
Odf::saveColRowCell(Sheet *sheet, int maxCols, int maxRows, OdfSavingContex  if \
                (repeated > 1)
                 xmlWriter.addAttribute("table:number-rows-repeated", repeated);
             if (!style.isDefault()) {
-                KoGenStyle currentDefaultCellStyle; // the type is determined in \
saveOdfCellStyle +                KoGenStyle currentDefaultCellStyle; // the type is \
determined in saveCellStyle  #warning TODO new style odf
                 const QString name = style.saveOdf(currentDefaultCellStyle, \
                mainStyles,
                                                    sheet->map()->styleManager());
@@ -1318,7 +1330,7 @@ void Odf::saveColRowCell(Sheet *sheet, int maxCols, int \
maxRows, OdfSavingContex  i = j - 1; /*it's already incremented in the for loop*/
         } else { // row is not empty
             if (!style.isDefault()) {
-                KoGenStyle currentDefaultCellStyle; // the type is determined in \
saveOdfCellStyle +                KoGenStyle currentDefaultCellStyle; // the type is \
determined in saveCellStyle  #warning TODO new style odf
                 const QString name = style.saveOdf(currentDefaultCellStyle, \
                mainStyles,
                                                    sheet->map()->styleManager());
@@ -1389,8 +1401,7 @@ void Odf::saveCells(Sheet *sheet, int row, int maxCols, \
OdfSavingContext& tableC  
         int repeated = 1;
         int column = i;
-#warning TODO new style odf
-        cell.saveOdf(row, column, repeated, tableContext);
+        saveCell(&cell, repeated, tableContext);
         i += repeated;
         // stop if we reached the end column
         if (i > maxCols || nextCell.isNull())


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

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