File indexing completed on 2025-02-02 12:00:47

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org>
0003    SPDX-FileCopyrightText: 2005 Laurent Montel <montel@kde.org>
0004 
0005    SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 /* GNUmeric import filter by Phillip Ezolt 6-2-2001 */
0009 /*                        phillipezolt@hotmail.com  */
0010 /* additions: Norbert Andres nandres@web.de         */
0011 #include "gnumericimport.h"
0012 
0013 #include <QDomDocument>
0014 #include <QDebug>
0015 
0016 #include <KCompressionDevice>
0017 #include <kpluginfactory.h>
0018 
0019 #include <KoFilterChain.h>
0020 #include <KoPageFormat.h>
0021 #include <KoDocumentInfo.h>
0022 #include <KoUnit.h>
0023 
0024 // Calligra Sheets
0025 #include <sheets/engine/NamedAreaManager.h>
0026 #include <sheets/engine/Region.h>
0027 #include <sheets/engine/Util.h>
0028 #include <sheets/engine/ValueParser.h>
0029 #include <sheets/core/ApplicationSettings.h>
0030 #include <sheets/core/Cell.h>
0031 #include <sheets/core/ColFormatStorage.h>
0032 #include <sheets/core/HeaderFooter.h>
0033 #include <sheets/core/LoadingInfo.h>
0034 #include <sheets/core/Map.h>
0035 #include <sheets/core/PrintSettings.h>
0036 #include <sheets/core/RowFormatStorage.h>
0037 #include <sheets/core/Sheet.h>
0038 #include <sheets/core/Style.h>
0039 #include <sheets/part/Doc.h>
0040 
0041 #define SECS_PER_DAY 86400
0042 #define HALF_SEC (0.5 / SECS_PER_DAY)
0043 
0044 using namespace Calligra::Sheets;
0045 
0046 // copied from gnumeric: src/format.c:
0047 static const int g_dateSerial_19000228 = 59;
0048 /* One less that the Julian day number of 19000101.  */
0049 static int g_dateOrigin = 0;
0050 
0051 // copied from gnumeric: src/formats.c:
0052 static char const * const cell_date_format [] = {
0053     "m/d/yy",  /* 0 Cell::Format::Date5*/
0054     "m/d/yyyy",  /* 1 Cell::Format::Date6*/
0055     "d-mmm-yy",  /* 2 Cell::Format::Date1 18-Feb-99 */
0056     "d-mmm-yyyy",  /* 3 Cell::Format::Date2 18-Feb-1999 */
0057     "d-mmm",  /* 4 Cell::Format::Date3 18-Feb */
0058     "d-mm",   /* 5 Cell::Format::Date4 18-05 */
0059     "mmm/d",  /* 6 Cell::Format::Date11*/
0060     "mm/d",   /* 7 Cell::Format::Date12*/
0061     "mm/dd/yy",  /* 8 Cell::Format::Date19*/
0062     "mm/dd/yyyy",  /* 9 Cell::Format::Date18*/
0063     "mmm/dd/yy",  /* 10 Cell::Format::Date20*/
0064     "mmm/dd/yyyy",  /* 11 Cell::Format::Date21*/
0065     "mmm/ddd/yy",  /* 12 */
0066     "mmm/ddd/yyyy",  /* 13 */
0067     "mm/ddd/yy",  /* 14 */
0068     "mm/ddd/yyyy",  /* 15 */
0069     "mmm-yy",  /* 16 Cell::Format::Date7*/
0070     "mmm-yyyy",  /* 17 Cell::Format::Date22*/
0071     "mmmm-yy",  /* 18 Cell::Format::Date8*/
0072     "mmmm-yyyy",  /* 19 Cell::Format::Date9*/
0073     "m/d/yy h:mm",  /* 20 */
0074     "m/d/yyyy h:mm", /* 21 */
0075     "yyyy/mm/d",  /* 22 Cell::Format::Date25*/
0076     "yyyy/mmm/d",  /* 23 Cell::Format::Date14*/
0077     "yyyy/mm/dd",  /* 24 Cell::Format::Date25*/
0078     "yyyy/mmm/dd",  /* 25 Cell::Format::Date26*/
0079     "yyyy-mm-d",  /* 26 Cell::Format::Date16*/
0080     "yyyy-mmm-d",  /* 27 Cell::Format::Date15*/
0081     "yyyy-mm-dd",  /* 28 Cell::Format::Date16*/
0082     "yyyy-mmm-dd",  /* 29 Cell::Format::Date15*/
0083     "yy",   /* 30 Cell::Format::Date24*/
0084     "yyyy",   /* 31 Cell::Format::Date23*/
0085     nullptr
0086 };
0087 
0088 // copied from gnumeric: src/formats.c:
0089 static char const * const cell_time_format [] = {
0090     "h:mm AM/PM",    // Cell::Format::Time1 9 : 01 AM
0091     "h:mm:ss AM/PM", // Cell::Format::Time2 9:01:05 AM
0092     "h:mm",          // Cell::Format::Time4 9:01
0093     "h:mm:ss",       // Cell::Format::Time5 9:01:12
0094     "m/d/yy h:mm",
0095     "mm:ss",         // Cell::Format::Time6 01:12
0096     "mm:ss.0",       // Cell::Format::Time6 01:12
0097     "[h]:mm:ss",
0098     "[h]:mm",
0099     "[mm]:ss",
0100     "[ss]",
0101     nullptr
0102 };
0103 
0104 namespace gnumeric_import_LNS
0105 {
0106 QStringList list1;
0107 QStringList list2;
0108 }
0109 
0110 using namespace gnumeric_import_LNS;
0111 
0112 void GNUMERICFilter::dateInit()
0113 {
0114     // idea copied form gnumeric src/format.c:
0115     /* Day 1 means 1st of January of 1900 */
0116     g_dateOrigin = GnumericDate::greg2jul(1900, 1, 1) - 1;
0117 }
0118 
0119 uint GNUMERICFilter::GnumericDate::greg2jul(int y, int m, int d)
0120 {
0121     return QDate(y, m, d).toJulianDay();
0122 }
0123 
0124 void GNUMERICFilter::GnumericDate::jul2greg(double num, int & y, int & m, int & d)
0125 {
0126     int i = (int) floor(num + HALF_SEC);
0127     if (i > g_dateSerial_19000228)
0128         --i;
0129     else if (i == g_dateSerial_19000228 + 1)
0130         qDebug() << "Request for date 02/29/1900.";
0131 
0132     qDebug() << "***** Num:" << num << ", i:" << i;
0133 
0134     QDate::fromJulianDay(i + g_dateOrigin).getDate(&y, &m, &d);
0135     qDebug() << "y:" << y << ", m:" << m << ", d:" << d;
0136 }
0137 
0138 QTime GNUMERICFilter::GnumericDate::getTime(double num)
0139 {
0140     // idea copied from gnumeric: src/datetime.c
0141     num += HALF_SEC;
0142     int secs = qRound((num - floor(num)) * SECS_PER_DAY);
0143 
0144     qDebug() << "***** Num:" << num << ", secs" << secs;
0145 
0146     const int h = secs / 3600;
0147     secs -= h * 3600;
0148     const int m = secs / 60;
0149     secs -= h * 60;
0150 
0151     qDebug() << "****** h:" << h << ", m:" << m << ", secs:" << secs;
0152     const QTime time(h, m, (secs < 0 || secs > 59 ? 0 : secs));
0153 
0154     return time;
0155 }
0156 
0157 K_PLUGIN_FACTORY_WITH_JSON(GNUMERICFilterFactory, "calligra_filter_gnumeric2sheets.json",
0158                            registerPlugin<GNUMERICFilter>();)
0159 
0160 GNUMERICFilter::GNUMERICFilter(QObject* parent, const QVariantList &)
0161         : KoFilter(parent)
0162 {
0163 }
0164 
0165 /* This converts GNUmeric's color string "0:0:0" to a QColor. */
0166 void  convert_string_to_qcolor(const QString &color_string, QColor * color)
0167 {
0168     int red, green, blue, first_col_pos, second_col_pos;
0169 
0170     bool number_ok;
0171 
0172     first_col_pos  = color_string.indexOf(':', 0);
0173     second_col_pos = color_string.indexOf(':', first_col_pos + 1);
0174 
0175     /* Fore="0:0:FF00" */
0176     /* If GNUmeric kicks out some invalid colors, we could crash. */
0177     /* GNUmeric gives us two bytes of color data per element. */
0178     /* We only care about the top byte. */
0179 
0180     red   = color_string.midRef(0, first_col_pos).toInt(&number_ok, 16) >> 8;
0181     green = color_string.midRef(first_col_pos + 1,
0182                              (second_col_pos - first_col_pos) - 1).toInt(&number_ok, 16) >> 8;
0183     blue  = color_string.midRef(second_col_pos + 1,
0184                              (color_string.length() - first_col_pos) - 1).toInt(&number_ok, 16) >> 8;
0185     color->setRgb(red, green, blue);
0186 }
0187 
0188 void areaNames(Doc * ksdoc, const QString &_name, QString _zone)
0189 {
0190 //Sheet2!$A$2:$D$8
0191     QString tableName;
0192     int pos = _zone.indexOf('!');
0193     if (pos != -1) {
0194         tableName = _zone.left(pos);
0195         _zone = _zone.right(_zone.length() - pos - 1);
0196         pos = _zone.indexOf(':');
0197         QRect rect;
0198         if (pos != -1) {
0199             QString left = _zone.mid(1, pos - 1);
0200             QString right = _zone.mid(pos + 2, _zone.length() - pos - 2);
0201             int pos = left.indexOf('$');
0202 
0203             rect.setLeft(Util::decodeColumnLabelText(left.left(pos)));
0204             rect.setTop(left.rightRef(left.length() - pos - 1).toInt());
0205 
0206             pos = right.indexOf('$');
0207             rect.setRight(Util::decodeColumnLabelText(right.left(pos)));
0208             rect.setBottom(right.rightRef(right.length() - pos - 1).toInt());
0209         } else {
0210             QString left = _zone;
0211             int pos = left.indexOf('$');
0212             int leftPos = Util::decodeColumnLabelText(left.left(pos));
0213             rect.setLeft(leftPos);
0214             rect.setRight(leftPos);
0215 
0216             int top = left.rightRef(left.length() - pos - 1).toInt();
0217             rect.setTop(top);
0218             rect.setBottom(top);
0219         }
0220         ksdoc->map()->namedAreaManager()->insert(Calligra::Sheets::Region(rect, ksdoc->map()->findSheet(tableName)), _name);
0221     }
0222 }
0223 
0224 
0225 void set_document_area_names(Doc * ksdoc, QDomElement * docElem)
0226 {
0227     QDomNode areaNamesElement = docElem->namedItem("Names");
0228     if (areaNamesElement.isNull())
0229         return;
0230     QDomNode areaNameItem = areaNamesElement.namedItem("Name");
0231     while (!areaNameItem.isNull()) {
0232         QDomNode gmr_name  = areaNameItem.namedItem("name");
0233         QDomNode gmr_value = areaNameItem.namedItem("value");
0234         QString name = gmr_name.toElement().text();
0235         areaNames(ksdoc, name, gmr_value.toElement().text());
0236         areaNameItem = areaNameItem.nextSibling();
0237     }
0238 }
0239 
0240 
0241 
0242 void set_document_attributes(Doc * ksdoc, QDomElement * docElem)
0243 {
0244     ksdoc->loadConfigFromFile();
0245     QDomNode attributes  = docElem->namedItem("Attributes");
0246     if (attributes.isNull())
0247         return;
0248 
0249     QDomNode attributeItem = attributes.namedItem("Attribute");
0250     ApplicationSettings *sett = ksdoc->map()->applicationSettings();
0251     while (!attributeItem.isNull()) {
0252         QDomNode gmr_name  = attributeItem.namedItem("name");
0253         QDomNode gmr_value = attributeItem.namedItem("value");
0254         if (gmr_name.toElement().text() == "WorkbookView::show_horizontal_scrollbar") {
0255             sett->setShowHorizontalScrollBar(gmr_value.toElement().text().toLower() == "true" ? true : false);
0256         } else if (gmr_name.toElement().text() == "WorkbookView::show_vertical_scrollbar") {
0257             sett->setShowVerticalScrollBar(gmr_value.toElement().text().toLower() == "true" ? true : false);
0258         } else if (gmr_name.toElement().text() == "WorkbookView::show_notebook_tabs") {
0259             sett->setShowTabBar(gmr_value.toElement().text().toLower() == "true" ? true : false);
0260         } else if (gmr_name.toElement().text() == "WorkbookView::do_auto_completion") {
0261             sett->setCompletionMode(KCompletion::CompletionAuto);
0262         } else if (gmr_name.toElement().text() == "WorkbookView::is_protected") {
0263             //TODO protect document ???
0264             //ksdoc->map()->isProtected()
0265         }
0266 
0267         attributeItem = attributeItem.nextSibling();
0268     }
0269 }
0270 
0271 /* This sets the documentation information from the information stored in
0272    the GNUmeric file. Particularly in the "Summary" subcategory.
0273 */
0274 void set_document_info(KoDocument * document, QDomElement * docElem)
0275 {
0276     /* Summary Handling START */
0277     QDomNode summary  = docElem->namedItem("Summary");
0278     QDomNode gmr_item = summary.namedItem("Item");
0279 
0280     while (!gmr_item.isNull()) {
0281         QDomNode gmr_name  = gmr_item.namedItem("name");
0282         QDomNode gmr_value = gmr_item.namedItem("val-string");
0283 
0284         KoDocumentInfo * DocumentInfo     = document->documentInfo();
0285 
0286         if (gmr_name.toElement().text() == "title") {
0287             DocumentInfo->setAboutInfo("title", gmr_value.toElement().text());
0288         } else if (gmr_name.toElement().text() == "keywords") {
0289             DocumentInfo->setAboutInfo("keyword", gmr_value.toElement().text());
0290         } else if (gmr_name.toElement().text() == "comments") {
0291             DocumentInfo->setAboutInfo("comments", gmr_value.toElement().text());
0292         } else if (gmr_name.toElement().text() == "category") {
0293             /* Not supported by Calligra::Sheets */
0294         } else if (gmr_name.toElement().text() == "manager") {
0295             /* Not supported by Calligra::Sheets */
0296         } else if (gmr_name.toElement().text() == "application") {
0297             /* Not supported by Calligra::Sheets */
0298         } else if (gmr_name.toElement().text() == "author") {
0299             DocumentInfo->setAuthorInfo("creator", gmr_value.toElement().text());
0300         } else if (gmr_name.toElement().text() == "company") {
0301             DocumentInfo->setAuthorInfo("company", gmr_value.toElement().text());
0302         }
0303 
0304         gmr_item = gmr_item.nextSibling();
0305     }
0306 
0307     /* Summany Handling STOP */
0308 }
0309 
0310 
0311 void setColInfo(QDomNode * sheet, Sheet * table)
0312 {
0313     QDomNode columns =  sheet->namedItem("Cols");
0314     QDomNode columninfo = columns.namedItem("ColInfo");
0315 
0316     double defaultWidth = 0.0;
0317     bool defaultWidthOk = false;
0318 
0319     QDomElement def = columns.toElement();
0320     if (def.hasAttribute("DefaultSizePts")) {
0321         defaultWidth = def.attribute("DefaultSizePts").toDouble(&defaultWidthOk);
0322     }
0323 
0324     ColFormatStorage *cf = table->columnFormats();
0325     while (!columninfo.isNull()) {
0326         QDomElement e = columninfo.toElement(); // try to convert the node to an element.
0327         int column_number = e.attribute("No").toInt() + 1;
0328         if (e.hasAttribute("Hidden")) {
0329             if (e.attribute("Hidden") == "1") {
0330                 cf->setHidden(column_number, column_number, true);
0331             }
0332         }
0333         if (e.hasAttribute("Unit")) {
0334             //  xmm = (x_points) * (1 inch / 72 points) * (25.4 mm/ 1 inch)
0335             bool ok = false;
0336             double dbl = e.attribute("Unit").toDouble(&ok);
0337             if (ok)
0338                 cf->setColWidth(column_number, column_number, dbl);
0339             else if (defaultWidthOk)
0340                 cf->setColWidth(column_number, column_number, defaultWidth);
0341         }
0342         columninfo = columninfo.nextSibling();
0343     }
0344 }
0345 
0346 void setRowInfo(QDomNode *sheet, Sheet *table)
0347 {
0348     QDomNode rows =  sheet->namedItem("Rows");
0349     QDomNode rowinfo = rows.namedItem("RowInfo");
0350 
0351     double defaultHeight = 0.0;
0352     bool defaultHeightOk = false;
0353 
0354     QDomElement def = rows.toElement();
0355     if (def.hasAttribute("DefaultSizePts")) {
0356         defaultHeight = def.attribute("DefaultSizePts").toDouble(&defaultHeightOk);
0357     }
0358 
0359     RowFormatStorage *rf = table->rowFormats();
0360     while (!rowinfo.isNull()) {
0361         QDomElement e = rowinfo.toElement(); // try to convert the node to an element.
0362         int row_number = e.attribute("No").toInt() + 1;
0363 
0364         if (e.hasAttribute("Hidden")) {
0365             if (e.attribute("Hidden") == "1") {
0366                 rf->setHidden(row_number, row_number, true);
0367             }
0368         }
0369         if (e.hasAttribute("Unit")) {
0370             bool ok = false;
0371             double dbl = e.attribute("Unit").toDouble(&ok);
0372             if (ok)
0373                 rf->setRowHeight(row_number, row_number, dbl);
0374             else if (defaultHeightOk)
0375                 rf->setRowHeight(row_number, row_number, defaultHeight);
0376         }
0377         rowinfo = rowinfo.nextSibling();
0378     }
0379 }
0380 
0381 void setSelectionInfo(QDomNode * sheet, Sheet * /* table */)
0382 {
0383     QDomNode selections =  sheet->namedItem("Selections");
0384     QDomNode selection = selections.namedItem("Selection");
0385 
0386     /* Calligra Sheets does not support multiple selections.. */
0387     /* This code will set the selection to the last one GNUmeric's multiple
0388        selections. */
0389     while (!selection.isNull()) {
0390         QDomElement e = selection.toElement(); // try to convert the node to an element.
0391         QRect kspread_selection;
0392 
0393         kspread_selection.setLeft((e.attribute("startCol").toInt() + 1));
0394         kspread_selection.setTop((e.attribute("startRow").toInt() + 1));
0395         kspread_selection.setRight((e.attribute("endCol").toInt() + 1));
0396         kspread_selection.setBottom((e.attribute("endRow").toInt() + 1));
0397 
0398         /* can't set it in the table -- must set it to a view */
0399         //   table->setSelection(kspread_selection);
0400 
0401         selection = selection.nextSibling();
0402     }
0403 }
0404 
0405 
0406 void setObjectInfo(QDomNode * sheet, Sheet * table)
0407 {
0408     QDomNode gmr_objects =  sheet->namedItem("Objects");
0409     QDomNode gmr_cellcomment = gmr_objects.namedItem("CellComment");
0410     while (!gmr_cellcomment.isNull()) {
0411         QDomElement e = gmr_cellcomment.toElement(); // try to convert the node to an element.
0412         if (e.hasAttribute("Text")) {
0413             if (e.hasAttribute("ObjectBound")) {
0414                 const Calligra::Sheets::Region region = table->map()->regionFromName(e.attribute("ObjectBound"), table);
0415                 Cell cell = Cell(table, region.firstRange().topLeft());
0416                 cell.setComment(e.attribute("Text"));
0417             }
0418         }
0419 
0420         gmr_cellcomment  = gmr_cellcomment.nextSibling();
0421     }
0422 }
0423 
0424 void convertToPen(QPen & pen, int style)
0425 {
0426     switch (style) {
0427     case 0:
0428         break;
0429     case 1:
0430         pen.setStyle(Qt::SolidLine);
0431         pen.setWidth(1);
0432         break;
0433     case 2:
0434         pen.setStyle(Qt::SolidLine);
0435         pen.setWidth(2);
0436         break;
0437     case 3:
0438         pen.setStyle(Qt::DashLine);
0439         pen.setWidth(1);
0440         break;
0441     case 4:
0442         // width should be 1 but otherwise it would be the same as 7
0443         pen.setStyle(Qt::DotLine);
0444         pen.setWidth(2);
0445         break;
0446     case 5:
0447         pen.setStyle(Qt::SolidLine);
0448         pen.setWidth(3);
0449         break;
0450     case 6:
0451         // TODO should be double
0452         pen.setStyle(Qt::SolidLine);
0453         pen.setWidth(1);
0454         break;
0455     case 7:
0456         // very thin dots => no match in Calligra::Sheets
0457         pen.setStyle(Qt::DotLine);
0458         pen.setWidth(1);
0459         break;
0460     case 8:
0461         pen.setStyle(Qt::DashLine);
0462         pen.setWidth(2);
0463         break;
0464     case 9:
0465         pen.setStyle(Qt::DashDotLine);
0466         pen.setWidth(1);
0467         break;
0468     case 10:
0469         pen.setStyle(Qt::DashDotLine);
0470         pen.setWidth(2);
0471         break;
0472     case 11:
0473         pen.setStyle(Qt::DashDotDotLine);
0474         pen.setWidth(1);
0475         break;
0476     case 12:
0477         pen.setStyle(Qt::DashDotDotLine);
0478         pen.setWidth(2);
0479         break;
0480     case 13:
0481         // TODO: long dash, short dash, long dash,...
0482         pen.setStyle(Qt::DashDotLine);
0483         pen.setWidth(3);
0484         break;
0485     default:
0486         pen.setStyle(Qt::SolidLine);
0487         pen.setWidth(1);
0488     }
0489 }
0490 
0491 void GNUMERICFilter::ParseBorder(QDomElement & gmr_styleborder, const Cell& kspread_cell)
0492 {
0493     QDomNode gmr_diagonal = gmr_styleborder.namedItem("Diagonal");
0494     QDomNode gmr_rev_diagonal = gmr_styleborder.namedItem("Rev-Diagonal");
0495     QDomNode gmr_top = gmr_styleborder.namedItem("Top");
0496     QDomNode gmr_bottom = gmr_styleborder.namedItem("Bottom");
0497     QDomNode gmr_left = gmr_styleborder.namedItem("Left");
0498     QDomNode gmr_right = gmr_styleborder.namedItem("Right");
0499 
0500     // NoPen - no line at all. For example,
0501     // QPainter::drawRect() fills but does not
0502     // draw any explicit boundary
0503     // line. SolidLine - a simple line. DashLine
0504     // - dashes, separated by a few
0505     // pixels. DotLine - dots, separated by a
0506     // few pixels. DashDotLine - alternately
0507     // dots and dashes. DashDotDotLine - one dash, two dots, one dash, two dots...
0508 
0509     if (!gmr_left.isNull()) {
0510         QDomElement e = gmr_left.toElement(); // try to convert the node to an element.
0511         importBorder(e, Left, kspread_cell);
0512     }
0513 
0514     if (!gmr_right.isNull()) {
0515         QDomElement e = gmr_right.toElement(); // try to convert the node to an element.
0516         importBorder(e, Right, kspread_cell);
0517     }
0518 
0519     if (!gmr_top.isNull()) {
0520         QDomElement e = gmr_top.toElement(); // try to convert the node to an element.
0521         importBorder(e, Top,  kspread_cell);
0522     }
0523 
0524     if (!gmr_bottom.isNull()) {
0525         QDomElement e = gmr_bottom.toElement(); // try to convert the node to an element.
0526         importBorder(e, Bottom, kspread_cell);
0527     }
0528 
0529     if (!gmr_diagonal.isNull()) {
0530         QDomElement e = gmr_diagonal.toElement(); // try to convert the node to an element.
0531         importBorder(e, Diagonal, kspread_cell);
0532     }
0533 
0534     if (!gmr_rev_diagonal.isNull()) {
0535         QDomElement e = gmr_rev_diagonal.toElement(); // try to convert the node to an element.
0536         importBorder(e, Revdiagonal, kspread_cell);
0537     }
0538 
0539     //  QDomElement gmr_styleborder_element = gmr_styleborder.toElement();
0540 }
0541 
0542 
0543 void GNUMERICFilter::importBorder(QDomElement border, borderStyle _style, const Calligra::Sheets::Cell& cell)
0544 {
0545     if (!border.isNull()) {
0546         QDomElement e = border.toElement(); // try to convert the node to an element.
0547         if (e.hasAttribute("Style")) {
0548             Style style;
0549             int penStyle = e.attribute("Style").toInt();
0550 
0551             QPen pen;
0552             convertToPen(pen, penStyle);
0553             QPen leftPen(Qt::NoPen);
0554             QPen rightPen(Qt::NoPen);
0555             QPen topPen(Qt::NoPen);
0556             QPen bottomPen(Qt::NoPen);
0557             QPen fallPen(Qt::NoPen);
0558             QPen goUpPen(Qt::NoPen);
0559 
0560             if (penStyle > 0) {
0561                 switch (_style) {
0562                 case Left:
0563                     leftPen = pen;
0564                     break;
0565                 case Right:
0566                     rightPen = pen;
0567                     break;
0568                 case Top:
0569                     topPen = pen;
0570                     break;
0571                 case Bottom:
0572                     bottomPen = pen;
0573                     break;
0574                 case Diagonal:
0575                     fallPen = pen;
0576                     break;
0577                 case Revdiagonal:
0578                     goUpPen = pen;
0579                     break;
0580                 }
0581             }
0582             if (e.hasAttribute("Color")) {
0583                 QColor color;
0584                 QString colorString = e.attribute("Color");
0585                 convert_string_to_qcolor(colorString, &color);
0586                 {
0587                     switch (_style) {
0588                     case Left:
0589                         leftPen.setColor(color);
0590                         break;
0591                     case Right:
0592                         rightPen.setColor(color);
0593                         break;
0594                     case Top:
0595                         topPen.setColor(color);
0596                         break;
0597                     case Bottom:
0598                         bottomPen.setColor(color);
0599                         break;
0600                     case Diagonal:
0601                         fallPen.setColor(color);
0602                         break;
0603                     case Revdiagonal:
0604                         goUpPen.setColor(color);
0605                         break;
0606                     }
0607                 }
0608             }
0609             if (leftPen.style() != Qt::NoPen) style.setLeftBorderPen(leftPen);
0610             if (rightPen.style() != Qt::NoPen) style.setRightBorderPen(rightPen);
0611             if (topPen.style() != Qt::NoPen) style.setTopBorderPen(topPen);
0612             if (bottomPen.style() != Qt::NoPen) style.setBottomBorderPen(bottomPen);
0613             if (fallPen.style() != Qt::NoPen) style.setFallDiagonalPen(fallPen);
0614             if (goUpPen.style() != Qt::NoPen) style.setGoUpDiagonalPen(goUpPen);
0615             Cell(cell).setStyle(style);
0616         }
0617     }
0618 }
0619 
0620 bool GNUMERICFilter::setType(const Cell& kspread_cell,
0621                              QString const & formatString,
0622                              QString & cell_content)
0623 {
0624     int i = 0;
0625     for (i = 0; cell_date_format[i] ; ++i) {
0626         qDebug() << "Format::Cell:" << cell_date_format[i] << ", FormatString:" << formatString;
0627         if ((formatString == "d/m/yy") || (formatString == cell_date_format[i])) {
0628             qDebug() << "   FormatString: Date:" << formatString << ", CellContent:" << cell_content;
0629             QDate date;
0630             if (!kspread_cell.isDate()) {
0631                 // convert cell_content to date
0632                 int y, m, d;
0633                 bool ok = true;
0634                 int val  = cell_content.toInt(&ok);
0635 
0636                 qDebug() << "!!!   FormatString: Date:" << formatString << ", CellContent:" << cell_content
0637                 << ", Double: " << val << endl;
0638                 if (!ok)
0639                     return false;
0640 
0641                 GnumericDate::jul2greg(val, y, m, d);
0642                 qDebug() << "     num:" << val << ", y:" << y << ", m:" << m << ", d:" << d;
0643 
0644                 date.setDate(y, m, d);
0645             } else
0646                 date = kspread_cell.value().asDate(kspread_cell.sheet()->map()->calculationSettings());
0647 
0648             Format::Type type;
0649 
0650             switch (i) {
0651             case 0:  type = Format::ShortDate;  break;
0652             case 1:  type = Format::TextDate;  break;
0653             case 2:  type = Format::Date1;  break;
0654             case 3:  type = Format::Date2;  break;
0655             case 10: type = Format::Date7; break;
0656 //            case 11: type = Format::Date8; break;
0657             default:
0658                 type = Format::ShortDate;
0659                 break;
0660                 /* 12, 13, 14, 15, 20, 21 */
0661             }
0662 
0663             qDebug() << "i:" << i << ", Type:" << type << ", Date:" << date.toString();
0664 
0665             Cell cell(kspread_cell);
0666             cell.setValue(Value(date, kspread_cell.sheet()->map()->calculationSettings()));
0667             Style style;
0668             style.setFormatType(type);
0669             cell.setStyle(style);
0670 
0671             return true;
0672         }
0673     }
0674 
0675     for (i = 0; cell_time_format[i] ; ++i) {
0676         if (formatString == cell_time_format[i]) {
0677             QTime time;
0678 
0679             if (!kspread_cell.isTime()) {
0680                 bool ok = true;
0681                 double content = cell_content.toDouble(&ok);
0682 
0683                 qDebug() << "   FormatString: Time:" << formatString << ", CellContent:" << cell_content
0684                 << ", Double: " << content << endl;
0685 
0686                 if (!ok)
0687                     return false;
0688 
0689                 time = GnumericDate::getTime(content);
0690             } else
0691                 time = kspread_cell.value().asTime().toQTime();
0692 
0693             Format::Type type;
0694             switch (i) {
0695             case 0: type = Format::Time1; break;
0696             case 1: type = Format::Time2; break;
0697             case 2: type = Format::Time4; break;
0698             case 3: type = Format::Time5; break;
0699             case 8: type = Format::DurationHourShort; break;
0700             case 9: type = Format::DurationMinute; break;
0701             default:
0702                 type = Format::Time1; break;
0703             }
0704 
0705             qDebug() << "i:" << i << ", Type:" << type;
0706             Cell cell(kspread_cell);
0707             cell.setValue(Value(Time(time)));
0708             Style style;
0709             style.setFormatType(type);
0710             cell.setStyle(style);
0711 
0712             return true;
0713         }
0714     }
0715 
0716     return false; // no date or time
0717 }
0718 
0719 QString GNUMERICFilter::convertVars(QString const & str, Sheet * table) const
0720 {
0721     QString result(str);
0722     uint count = list1.count();
0723     if (count == 0) {
0724         list1 << "&[TAB]" << "&[DATE]" << "&[PAGE]"
0725         << "&[PAGES]" << "&[TIME]" << "&[FILE]";
0726         list2 << "<sheet>" << "<date>" << "<page>"
0727         << "<pages>" << "<time>" << "<file>";
0728         count = list1.count();
0729     }
0730 
0731     for (uint i = 0; i < count; ++i) {
0732         int n = result.indexOf(list1[i]);
0733 
0734         if (n != -1) {
0735             qDebug() << "Found var:" << list1[i];
0736             if (i == 0)
0737                 result.replace(list1[i], table->sheetName());
0738             else
0739                 result.replace(list1[i], list2[i]);
0740         }
0741     }
0742 
0743     return result;
0744 }
0745 
0746 double GNUMERICFilter::parseAttribute(const QDomElement &_element)
0747 {
0748     QString unit = _element.attribute("PrefUnit");
0749     bool ok;
0750     double value = _element.attribute("Points").toFloat(&ok);
0751     if (!ok)
0752         value = 2.0;
0753     if (unit == "mm")
0754         return POINT_TO_MM(value);
0755     else if (unit == "cm")
0756         return (POINT_TO_MM(value) / 10.0);
0757     else if (unit == "in")
0758         return POINT_TO_INCH(value);
0759     else if (unit == "Pt" || unit == "Px" || unit == "points")
0760         return value;
0761     else
0762         return value;
0763 }
0764 
0765 void GNUMERICFilter::ParsePrintInfo(QDomNode const & printInfo, Sheet * table)
0766 {
0767     qDebug() << "Parsing print info";
0768 
0769     float fleft = 2.0;
0770     float fright = 2.0;
0771     float ftop = 2.0;
0772     float fbottom = 2.0;
0773 
0774     QString paperSize("A4");
0775     QString orientation("Portrait");
0776     QString footLeft, footMiddle, footRight;
0777     QString headLeft, headMiddle, headRight; // no we are zombies :-)
0778 
0779     QDomNode margins(printInfo.namedItem("Margins"));
0780     if (!margins.isNull()) {
0781         QDomElement top(margins.namedItem("top").toElement());
0782         if (!top.isNull())
0783             ftop = parseAttribute(top);
0784 
0785         QDomElement bottom(margins.namedItem("bottom").toElement());
0786         if (!bottom.isNull())
0787             fbottom = parseAttribute(bottom);
0788 
0789         QDomElement left(margins.namedItem("left").toElement());
0790         if (!left.isNull())
0791             fleft = parseAttribute(left);
0792 
0793         QDomElement right(margins.namedItem("right").toElement());
0794         if (!right.isNull())
0795             fright = parseAttribute(right);
0796     }
0797 
0798     QDomElement foot(printInfo.namedItem("Footer").toElement());
0799     if (!foot.isNull()) {
0800         qDebug() << "Parsing footer:" << foot.attribute("Left") << "," << foot.attribute("Middle") << ","
0801         << foot.attribute("Right") << ", " << endl;
0802         if (foot.hasAttribute("Left"))
0803             footLeft = convertVars(foot.attribute("Left"), table);
0804         if (foot.hasAttribute("Middle"))
0805             footMiddle = convertVars(foot.attribute("Middle"), table);
0806         if (foot.hasAttribute("Right"))
0807             footRight = convertVars(foot.attribute("Right"), table);
0808     }
0809 
0810     QDomElement head(printInfo.namedItem("Header").toElement());
0811     if (!head.isNull()) {
0812         qDebug() << "Parsing header:" << head.attribute("Left") << "," << head.attribute("Middle") << "," << head.attribute("Right") << ",";
0813         if (head.hasAttribute("Left"))
0814             headLeft = convertVars(head.attribute("Left"), table);
0815         if (head.hasAttribute("Middle"))
0816             headMiddle = convertVars(head.attribute("Middle"), table);
0817         if (head.hasAttribute("Right"))
0818             headRight = convertVars(head.attribute("Right"), table);
0819     }
0820 
0821     QDomElement repeateColumn(printInfo.namedItem("repeat_top").toElement());
0822     if (!repeateColumn.isNull()) {
0823         QString repeate = repeateColumn.attribute("value");
0824         if (!repeate.isEmpty()) {
0825             const Calligra::Sheets::Region region = table->map()->regionFromName(repeate, table);
0826             //kDebug()<<" repeate :"<<repeate<<"range. ::start row :"<<range.startRow ()<<" start col :"<<range.startCol ()<<" end row :"<<range.endRow ()<<" end col :"<<range.endCol ();
0827             table->printSettings()->setRepeatedRows(qMakePair(region.firstRange().top(), region.firstRange().bottom()));
0828         }
0829     }
0830 
0831     QDomElement repeateRow(printInfo.namedItem("repeat_left").toElement());
0832     if (!repeateRow.isNull()) {
0833         QString repeate = repeateRow.attribute("value");
0834         if (!repeate.isEmpty()) {
0835             //fix row too high
0836             repeate.replace("65536", "32500");
0837             const Calligra::Sheets::Region region = table->map()->regionFromName(repeate, table);
0838             //kDebug()<<" repeate :"<<repeate<<"range. ::start row :"<<range.startRow ()<<" start col :"<<range.startCol ()<<" end row :"<<range.endRow ()<<" end col :"<<range.endCol ();
0839             table->printSettings()->setRepeatedColumns(qMakePair(region.firstRange().left(), region.firstRange().right()));
0840         }
0841     }
0842 
0843     QDomElement orient(printInfo.namedItem("orientation").toElement());
0844     if (!orient.isNull())
0845         orientation = orient.text();
0846 
0847     QDomElement size(printInfo.namedItem("paper").toElement());
0848     if (!size.isNull())
0849         paperSize = size.text();
0850 
0851     KoPageLayout pageLayout;
0852     pageLayout.format = KoPageFormat::formatFromString(paperSize);
0853     pageLayout.orientation = (orientation == "Portrait")
0854                              ? KoPageFormat::Portrait : KoPageFormat::Landscape;
0855     pageLayout.leftMargin   = fleft;
0856     pageLayout.rightMargin  = fright;
0857     pageLayout.topMargin    = ftop;
0858     pageLayout.bottomMargin = fbottom;
0859     table->printSettings()->setPageLayout(pageLayout);
0860 
0861     table->headerFooter()->setHeadFootLine(headLeft, headMiddle, headRight,
0862                                            footLeft, footMiddle, footRight);
0863 }
0864 
0865 void GNUMERICFilter::ParseFormat(QString const & formatString, const Cell& kspread_cell)
0866 {
0867     int l = formatString.length();
0868     int lastPos = 0;
0869 
0870     if (l == 0) return;
0871 
0872     Style style;
0873 
0874     if (l == 0 || formatString == "General") {
0875         style.setFormatType(Format::Generic);
0876     } else if (formatString[l - 1] == '%') {
0877         style.setFormatType(Format::Percentage);
0878     } else if (formatString[0] == '$') { // dollar
0879         style.setFormatType(Format::Money);
0880         Currency currency("$");
0881         style.setCurrency(currency);
0882         lastPos = 1;
0883     } else if (formatString.startsWith("£")) { // pound
0884         style.setFormatType(Format::Money);
0885         Currency currency("£");
0886         style.setCurrency(currency);
0887         lastPos = 1;
0888     } else if (formatString.startsWith("Â¥")) { // yen
0889         style.setFormatType(Format::Money);
0890         Currency currency("Â¥");
0891         style.setCurrency(currency);
0892         lastPos = 1;
0893     } else if (formatString.startsWith("€")) { // euro
0894         style.setFormatType(Format::Money);
0895         Currency currency("€");
0896         style.setCurrency(currency);
0897         lastPos = 1;
0898     } else if (l > 1) {
0899         if ((formatString[0] == '[') && (formatString[1] == '$')) {
0900             int n = formatString.indexOf(']');
0901             if (n != -1) {
0902                 style.setFormatType(Format::Money);
0903                 Currency currency(formatString.mid(2, n - 2));
0904                 style.setCurrency(currency);
0905             }
0906             lastPos = ++n;
0907         } else if (formatString.indexOf("E+0") != -1) {
0908             style.setFormatType(Format::Scientific);
0909         } else {
0910             // do pattern matching with gnumeric formats
0911             QString content(kspread_cell.value().asString());
0912 
0913             if (setType(kspread_cell, formatString, content))
0914                 return;
0915 
0916             if (formatString.indexOf("?/?") != -1) {
0917                 // TODO: fixme!
0918                 style.setFormatType(Format::fraction_three_digits);
0919                 Cell(kspread_cell).setStyle(style);
0920                 return;
0921             }
0922             // so it's nothing we want to understand:-)
0923             return;
0924         }
0925     }
0926 
0927     while (formatString[lastPos] == ' ')
0928         ++lastPos;
0929 
0930     // GetPrecision and decimal point, format of negative items...
0931 
0932     // thousands separator
0933     if (formatString[lastPos] == '#') {
0934         if (formatString[lastPos + 1] == ',')
0935             lastPos += 2;
0936         // since KSpread 1.3
0937         // kspread_cell.setThousandsSeparator( sep );
0938     }
0939 
0940     while (formatString[lastPos] == ' ')
0941         ++lastPos;
0942 
0943     int n = formatString.indexOf('.', lastPos);
0944     if (n != -1) {
0945         lastPos = n + 1;
0946         int precision = lastPos;
0947         while (formatString[precision] == '0')
0948             ++precision;
0949 
0950         int tmp = lastPos;
0951         lastPos = precision;
0952         precision -= tmp;
0953 
0954         style.setPrecision(precision);
0955     }
0956 
0957     bool red = false;
0958     if (formatString.indexOf("[RED]", lastPos) != -1) {
0959         red = true;
0960         style.setFloatColor(Style::NegRed);
0961     }
0962     if (formatString.indexOf('(', lastPos) != -1) {
0963         if (red)
0964             style.setFloatColor(Style::NegRedBrackets);
0965         else
0966             style.setFloatColor(Style::NegBrackets);
0967     }
0968     Cell(kspread_cell).setStyle(style);
0969 }
0970 
0971 void GNUMERICFilter::convertFormula(QString & formula) const
0972 {
0973     int n = formula.indexOf('=', 1);
0974 
0975     // TODO: check if we do not screw something up here...
0976     if (n != -1)
0977         formula.replace(n, 1, "==");
0978 
0979     bool inQuote1 = false;
0980     bool inQuote2 = false;
0981     int l = formula.length();
0982     for (int i = 0; i < l; ++i) {
0983         if (formula[i] == '\'')
0984             inQuote1 = !inQuote1;
0985         else if (formula[i] == '"')
0986             inQuote2 = !inQuote2;
0987         else if (formula[i] == ',' && !inQuote1 && !inQuote2)
0988             formula.replace(i, 1, ';');
0989     }
0990 }
0991 
0992 void GNUMERICFilter::setStyleInfo(QDomNode * sheet, Sheet * table)
0993 {
0994     qDebug() << "SetStyleInfo entered";
0995     ValueParser *const parser = table->map()->parser();
0996 
0997     int row, column;
0998     QDomNode styles =  sheet->namedItem("Styles");
0999     if (!styles.isNull()) {
1000         // Get a style region within that sheet.
1001         QDomNode style_region =  styles.namedItem("StyleRegion");
1002 
1003         while (!style_region.isNull()) {
1004             QDomElement e = style_region.toElement(); // try to convert the node to an element.
1005 
1006             QDomNode gnumericStyle = style_region.namedItem("Style");
1007             QDomNode font = gnumericStyle.namedItem("Font");
1008             QDomNode validation = gnumericStyle.namedItem("Validation");
1009             QDomNode gmr_styleborder = gnumericStyle.namedItem("StyleBorder");
1010             QDomNode hyperlink = gnumericStyle.namedItem("HyperLink");
1011             int startCol = e.attribute("startCol").toInt() + 1;
1012             int endCol   = e.attribute("endCol").toInt() + 1;
1013             int startRow = e.attribute("startRow").toInt() + 1;
1014             int endRow   = e.attribute("endRow").toInt() + 1;
1015 
1016             qDebug() << "------Style:" << startCol << ","
1017             << startRow << " - " << endCol << ", " << endRow << endl;
1018 
1019             if (endCol - startCol > 200 || endRow - startRow > 200) {
1020                 style_region = style_region.nextSibling();
1021                 continue;
1022             }
1023 
1024             for (column = startCol; column <= endCol; ++column) {
1025                 for (row = startRow; row <= endRow; ++row) {
1026                     qDebug() << "Cell:" << column << "," << row;
1027                     Cell kspread_cell(table, column, row);
1028                     Style style;
1029 
1030                     // don't create new cells -> don't apply format on empty cells, if bigger region
1031                     if ((kspread_cell.isDefault() || kspread_cell.isEmpty())
1032                             && ((endCol - startCol > 2) || (endRow - startRow > 2))) {
1033                         qDebug() << "CELL EMPTY OR RANGE TOO BIG";
1034                         continue;
1035                     }
1036 
1037                     QDomElement style_element = gnumericStyle.toElement(); // try to convert the node to an element.
1038 
1039                     qDebug() << "Style valid for Calligra Sheets";
1040                     kspread_cell = Cell(table, column, row);
1041 
1042                     if (style_element.hasAttribute("Fore")) {
1043                         QString color_string = style_element.attribute("Fore");
1044                         QColor color;
1045                         convert_string_to_qcolor(color_string, &color);
1046                         style.setFontColor(color);
1047                     }
1048 
1049                     if (style_element.hasAttribute("Back")) {
1050                         QString color_string = style_element.attribute("Back");
1051                         QColor color;
1052                         convert_string_to_qcolor(color_string, &color);
1053                         style.setBackgroundColor(color);
1054                     }
1055 
1056                     QBrush backgroundBrush;
1057                     if (style_element.hasAttribute("PatternColor")) {
1058                         QString color_string = style_element.attribute("PatternColor");
1059                         QColor color;
1060                         convert_string_to_qcolor(color_string, &color);
1061                         backgroundBrush.setColor(color);
1062                     }
1063 
1064                     if (style_element.hasAttribute("Shade")) {
1065                         /* Pattern's taken from: gnumeric's pattern.c */
1066                         /* if "TODO" added: doesn't match exactly the gnumeric one */
1067 
1068                         QString shade = style_element.attribute("Shade");
1069                         if (shade == "0") {
1070                             // nothing to do
1071                         } else if (shade == "1") {
1072                             /* 1 Solid */
1073                             //backgroundBrush.setStyle(Qt::SolidPattern);
1074                             //This is as empty
1075                             /* What should this be? */
1076 
1077                         } else if (shade == "2") {
1078                             /* 2 75% */
1079                             backgroundBrush.setStyle(Qt::Dense2Pattern);
1080                         } else if (shade == "3") {
1081                             /* 3 50% */
1082                             backgroundBrush.setStyle(Qt::Dense4Pattern);
1083                         } else if (shade == "4") {
1084                             backgroundBrush.setStyle(Qt::Dense5Pattern);
1085                             /* This should be 25%... All qt has is 37% */
1086 
1087                             /* 4 25% */
1088                         } else if (shade == "5") {
1089                             backgroundBrush.setStyle(Qt::Dense6Pattern);
1090                             /* 5 12.5% */
1091                         } else if (shade == "6") {
1092                             backgroundBrush.setStyle(Qt::Dense7Pattern);
1093                             /* 6 6.25% */
1094 
1095                         } else if (shade == "7") {
1096                             backgroundBrush.setStyle(Qt::HorPattern);
1097                             /* 7 Horizontal Stripe */
1098                         } else if (shade == "8") {
1099                             backgroundBrush.setStyle(Qt::VerPattern);
1100                             /* 8 Vertical Stripe */
1101                         } else if (shade == "9") {
1102                             backgroundBrush.setStyle(Qt::BDiagPattern);
1103                             /* 9 Reverse Diagonal Stripe */
1104                         } else if (shade == "10") {
1105                             /* 10 Diagonal Stripe */
1106                             backgroundBrush.setStyle(Qt::FDiagPattern);
1107                         } else if (shade == "11") {
1108                             /* 11 Diagonal Crosshatch */
1109                             backgroundBrush.setStyle(Qt::DiagCrossPattern);
1110                         } else if (shade == "12") {
1111                             /* 12 Thick Diagonal Crosshatch TODO!*/
1112                             backgroundBrush.setStyle(Qt::DiagCrossPattern);
1113                         } else if (shade == "13") {
1114                             /* 13 Thin Horizontal Stripe TODO: wrong: this is thick!*/
1115                             backgroundBrush.setStyle(Qt::HorPattern);
1116                         } else if (shade == "14") {
1117                             backgroundBrush.setStyle(Qt::VerPattern);
1118                         } else if (shade == "15") {
1119                             backgroundBrush.setStyle(Qt::FDiagPattern);
1120                         } else if (shade == "16") {
1121                             /* 16 Thick Reverse Stripe TODO:*/
1122                             backgroundBrush.setStyle(Qt::BDiagPattern);
1123                         } else if (shade == "17") {
1124                             backgroundBrush.setStyle(Qt::DiagCrossPattern);
1125                         } else if (shade == "18") {
1126                             backgroundBrush.setStyle(Qt::DiagCrossPattern);
1127                         } else if (shade == "19") {
1128                             /* 19 Applix small circle */
1129                         } else if (shade == "20") {
1130                             /* 20 Applix semicircle */
1131                         } else if (shade == "21") {
1132                             /* 21 Applix small thatch */
1133                         } else if (shade == "22") {
1134                             /* 22 Applix round thatch */
1135                         } else if (shade == "23") {
1136                             /* 23 Applix Brick */
1137                         } else if (shade == "24") {
1138                             /* 24 100% */
1139                             backgroundBrush.setStyle(Qt::SolidPattern);
1140                         } else if (shade == "25") {
1141                             /* 25 87.5% */
1142                             backgroundBrush.setStyle(Qt::Dense2Pattern);
1143                         }
1144                     }
1145                     style.setBackgroundBrush(backgroundBrush);
1146 
1147                     if (style_element.hasAttribute("Rotation")) {
1148                         int rot = style_element.attribute("Rotation").toInt();
1149                         style.setAngle(-1* rot);
1150                     }
1151                     if (style_element.hasAttribute("Indent")) {
1152                         double indent = style_element.attribute("Indent").toDouble();
1153                         // gnumeric saves indent in characters, we in points:
1154                         style.setIndentation(indent * 10.0);
1155                     }
1156 
1157                     if (style_element.hasAttribute("HAlign")) {
1158                         QString halign_string = style_element.attribute("HAlign");
1159 
1160                         if (halign_string == "1") {
1161                             /* General: No equivalent in Calligra Sheets. */
1162                         } else if (halign_string == "2") {
1163                             style.setHAlign(Style::Left);
1164                         } else if (halign_string == "4") {
1165                             style.setHAlign(Style::Right);
1166                         } else if (halign_string == "8") {
1167                             style.setHAlign(Style::Center);
1168                         } else if (halign_string == "16") {
1169                             /* Fill: No equivalent in Calligra Sheets. */
1170                         } else if (halign_string == "32") {
1171                             /* Justify: No equivalent in Calligra Sheets */
1172                         } else if (halign_string == "64") {
1173                             /* Centered across selection*/
1174                         }
1175 
1176                     }
1177 
1178                     if (style_element.hasAttribute("VAlign")) {
1179                         QString valign_string = style_element.attribute("VAlign");
1180 
1181                         if (valign_string == "1") {
1182                             /* General: No equivalent in Calligra Sheets. */
1183                             style.setVAlign(Style::Top);
1184                         } else if (valign_string == "2") {
1185                             style.setVAlign(Style::Bottom);
1186                         } else if (valign_string == "4") {
1187                             style.setVAlign(Style::Middle);
1188                         } else if (valign_string == "8") {
1189                             /* Justify: No equivalent in Calligra Sheets */
1190                         }
1191                     }
1192 
1193                     if (style_element.hasAttribute("WrapText")) {
1194                         QString multiRow = style_element.attribute("WrapText");
1195 
1196                         if (multiRow == "1")
1197                             style.setWrapText(true);
1198                     }
1199 
1200                     if (style_element.hasAttribute("Format")) {
1201                         QString formatString = style_element.attribute("Format");
1202 
1203                         qDebug() << "Format:" << formatString;
1204                         ParseFormat(formatString, kspread_cell);
1205 
1206                     } // End "Format"
1207 
1208                     if (!gmr_styleborder.isNull()) {
1209                         QDomElement style_element = gmr_styleborder.toElement(); // try to convert the node to an element.
1210                         ParseBorder(style_element, kspread_cell);
1211                     }
1212                     if (!validation.isNull()) {
1213                         QDomElement validation_element = validation.toElement();
1214                         if (!validation_element.isNull()) {
1215                             qDebug() << " Cell validation";
1216                             Validity kspread_validity = kspread_cell.validity();
1217                             if (validation_element.hasAttribute("AllowBlank") && validation_element.attribute("AllowBlank") == "true") {
1218                                 kspread_validity.setAllowEmptyCell(true);
1219                             }
1220                             if (validation_element.hasAttribute("Title")) {
1221                                 kspread_validity.setTitle(validation_element.attribute("Title"));
1222                             }
1223                             if (validation_element.hasAttribute("Message")) {
1224                                 kspread_validity.setMessage(validation_element.attribute("Message"));
1225                             }
1226                             if (validation_element.hasAttribute("Style")) {
1227                                 int value = validation_element.attribute("Style").toInt();
1228                                 switch (value) {
1229                                 case 0:
1230                                     kspread_validity.setDisplayMessage(false);
1231                                     break;
1232                                 case 1:
1233                                     kspread_validity.setAction(Validity::Stop);
1234                                     break;
1235                                 case 2:
1236                                     kspread_validity.setAction(Validity::Warning);
1237                                     break;
1238                                 case 3:
1239                                     kspread_validity.setAction(Validity::Information);
1240                                     break;
1241                                 default:
1242                                     qDebug() << " Error in validation style :" << value;
1243                                     break;
1244                                 }
1245                             }
1246                             QDomNode expression0 = validation_element.namedItem("Expression0");
1247                             QDomNode expression1 = validation_element.namedItem("Expression1");
1248                             //kDebug()<<" expression0.isNull()"<<expression0.isNull();
1249                             //kDebug()<<" expression1.isNull()"<<expression1.isNull();
1250                             if (validation_element.hasAttribute("Type")) {
1251                                 int valueOp = validation_element.attribute("Type").toInt();
1252                                 switch (valueOp) {
1253                                 case 0:
1254                                     kspread_validity.setRestriction(Validity::NoRestriction);
1255                                     break;
1256                                 case 1: {
1257                                     kspread_validity.setRestriction(Validity::Integer);
1258                                     if (validation_element.hasAttribute("Operator")) {
1259                                         const Value value1(expression0.toElement().text().toInt());
1260                                         const Value value2(expression1.toElement().text().toInt());
1261                                         int value = validation_element.attribute("Operator").toInt();
1262                                         switch (value) {
1263                                         case 0:
1264                                             kspread_validity.setCondition(Validity::Between);
1265                                             if (!expression0.isNull())
1266                                                 kspread_validity.setMinimumValue(value1);
1267                                             if (!expression1.isNull())
1268                                                 kspread_validity.setMaximumValue(value2);
1269                                             break;
1270                                         case 1:
1271                                             kspread_validity.setCondition(Validity::DifferentTo);
1272                                             if (!expression0.isNull())
1273                                                 kspread_validity.setMinimumValue(value1);
1274                                             if (!expression1.isNull())
1275                                                 kspread_validity.setMaximumValue(value2);
1276                                             break;
1277                                         case 2:
1278                                             kspread_validity.setCondition(Validity::Equal);
1279                                             if (!expression0.isNull())
1280                                                 kspread_validity.setMinimumValue(value1);
1281                                             break;
1282                                         case 3:
1283                                             kspread_validity.setCondition(Validity::Different);
1284                                             if (!expression0.isNull())
1285                                                 kspread_validity.setMinimumValue(value1);
1286                                             break;
1287                                         case 4:
1288                                             kspread_validity.setCondition(Validity::Superior);
1289                                             if (!expression0.isNull())
1290                                                 kspread_validity.setMinimumValue(value1);
1291                                             break;
1292                                         case 5:
1293                                             kspread_validity.setCondition(Validity::Inferior);
1294                                             if (!expression0.isNull())
1295                                                 kspread_validity.setMinimumValue(value1);
1296                                             break;
1297                                         case 6:
1298                                             kspread_validity.setCondition(Validity::SuperiorEqual);
1299                                             if (!expression0.isNull())
1300                                                 kspread_validity.setMinimumValue(value1);
1301                                             break;
1302                                         case 7:
1303                                             kspread_validity.setCondition(Validity::InferiorEqual);
1304                                             if (!expression0.isNull())
1305                                                 kspread_validity.setMinimumValue(value1);
1306                                             break;
1307                                         default:
1308                                             qDebug() << " Error in validation Operator :" << value;
1309                                             break;
1310                                         }
1311                                     }
1312                                 }
1313                                 break;
1314                                 case 2:
1315                                     kspread_validity.setRestriction(Validity::Number);
1316                                     if (validation_element.hasAttribute("Operator")) {
1317                                         const Value value1(expression0.toElement().text().toInt());
1318                                         const Value value2(expression1.toElement().text().toInt());
1319                                         int value = validation_element.attribute("Operator").toInt();
1320                                         switch (value) {
1321                                         case 0:
1322                                             kspread_validity.setCondition(Validity::Between);
1323                                             if (!expression0.isNull())
1324                                                 kspread_validity.setMinimumValue(value1);
1325                                             if (!expression1.isNull())
1326                                                 kspread_validity.setMaximumValue(value2);
1327                                             break;
1328                                         case 1:
1329                                             kspread_validity.setCondition(Validity::DifferentTo);
1330                                             if (!expression0.isNull())
1331                                                 kspread_validity.setMinimumValue(value1);
1332                                             if (!expression1.isNull())
1333                                                 kspread_validity.setMaximumValue(value2);
1334                                             break;
1335                                         case 2:
1336                                             kspread_validity.setCondition(Validity::Equal);
1337                                             if (!expression0.isNull())
1338                                                 kspread_validity.setMinimumValue(value1);
1339                                             break;
1340                                         case 3:
1341                                             kspread_validity.setCondition(Validity::Different);
1342                                             if (!expression0.isNull())
1343                                                 kspread_validity.setMinimumValue(value1);
1344                                             break;
1345                                         case 4:
1346                                             kspread_validity.setCondition(Validity::Superior);
1347                                             if (!expression0.isNull())
1348                                                 kspread_validity.setMinimumValue(value1);
1349                                             break;
1350                                         case 5:
1351                                             if (!expression0.isNull())
1352                                                 kspread_validity.setMinimumValue(value1);
1353                                             kspread_validity.setCondition(Validity::Inferior);
1354                                             break;
1355                                         case 6:
1356                                             kspread_validity.setCondition(Validity::SuperiorEqual);
1357                                             if (!expression0.isNull())
1358                                                 kspread_validity.setMinimumValue(value1);
1359                                             break;
1360                                         case 7:
1361                                             kspread_validity.setCondition(Validity::InferiorEqual);
1362                                             if (!expression0.isNull())
1363                                                 kspread_validity.setMinimumValue(value1);
1364                                             break;
1365                                         default:
1366                                             qDebug() << " Error in validation Operator :" << value;
1367                                             break;
1368                                         }
1369                                     }
1370                                     break;
1371                                 case 3:
1372                                     kspread_validity.setRestriction(Validity::List);
1373                                     break;
1374                                 case 4:
1375                                     kspread_validity.setRestriction(Validity::Date);
1376                                     if (validation_element.hasAttribute("Operator")) {
1377                                         const Value value1 = parser->tryParseDate(expression0.toElement().text());
1378                                         const Value value2 = parser->tryParseDate(expression1.toElement().text());
1379                                         int value = validation_element.attribute("Operator").toInt();
1380                                         switch (value) {
1381                                         case 0:
1382                                             kspread_validity.setCondition(Validity::Between);
1383                                             if (!expression0.isNull())
1384                                                 kspread_validity.setMinimumValue(value1);
1385                                             if (!expression1.isNull())
1386                                                 kspread_validity.setMaximumValue(value2);
1387 
1388                                             break;
1389                                         case 1:
1390                                             if (!expression0.isNull())
1391                                                 kspread_validity.setMinimumValue(value1);
1392                                             if (!expression1.isNull())
1393                                                 kspread_validity.setMaximumValue(value2);
1394                                             kspread_validity.setCondition(Validity::DifferentTo);
1395                                             break;
1396                                         case 2:
1397                                             if (!expression0.isNull())
1398                                                 kspread_validity.setMinimumValue(value1);
1399                                             kspread_validity.setCondition(Validity::Equal);
1400                                             break;
1401                                         case 3:
1402                                             if (!expression0.isNull())
1403                                                 kspread_validity.setMinimumValue(value1);
1404                                             kspread_validity.setCondition(Validity::Different);
1405                                             break;
1406                                         case 4:
1407                                             if (!expression0.isNull())
1408                                                 kspread_validity.setMinimumValue(value1);
1409                                             kspread_validity.setCondition(Validity::Superior);
1410                                             break;
1411                                         case 5:
1412                                             if (!expression0.isNull())
1413                                                 kspread_validity.setMinimumValue(value1);
1414                                             kspread_validity.setCondition(Validity::Inferior);
1415                                             break;
1416                                         case 6:
1417                                             if (!expression0.isNull())
1418                                                 kspread_validity.setMinimumValue(value1);
1419                                             kspread_validity.setCondition(Validity::SuperiorEqual);
1420                                             break;
1421                                         case 7:
1422                                             if (!expression0.isNull())
1423                                                 kspread_validity.setMinimumValue(value1);
1424                                             kspread_validity.setCondition(Validity::InferiorEqual);
1425                                             break;
1426                                         default:
1427                                             qDebug() << " Error in validation Operator :" << value;
1428                                             break;
1429                                         }
1430                                     }
1431                                     break;
1432                                 case 5:
1433                                     kspread_validity.setRestriction(Validity::Time);
1434                                     if (validation_element.hasAttribute("Operator")) {
1435                                         const Value value1 = parser->tryParseTime(expression0.toElement().text());
1436                                         const Value value2 = parser->tryParseTime(expression1.toElement().text());
1437                                         int value = validation_element.attribute("Operator").toInt();
1438                                         switch (value) {
1439                                         case 0:
1440                                             kspread_validity.setCondition(Validity::Between);
1441                                             if (!expression0.isNull())
1442                                                 kspread_validity.setMinimumValue(value1);
1443                                             if (!expression1.isNull())
1444                                                 kspread_validity.setMaximumValue(value2);
1445                                             break;
1446                                         case 1:
1447                                             if (!expression0.isNull())
1448                                                 kspread_validity.setMinimumValue(value1);
1449                                             if (!expression1.isNull())
1450                                                 kspread_validity.setMaximumValue(value2);
1451                                             kspread_validity.setCondition(Validity::DifferentTo);
1452                                             break;
1453                                         case 2:
1454                                             if (!expression0.isNull())
1455                                                 kspread_validity.setMinimumValue(value1);
1456                                             kspread_validity.setCondition(Validity::Equal);
1457                                             break;
1458                                         case 3:
1459                                             kspread_validity.setCondition(Validity::Different);
1460                                             break;
1461                                         case 4:
1462                                             if (!expression0.isNull())
1463                                                 kspread_validity.setMinimumValue(value1);
1464                                             kspread_validity.setCondition(Validity::Superior);
1465                                             break;
1466                                         case 5:
1467                                             kspread_validity.setCondition(Validity::Inferior);
1468                                             if (!expression0.isNull())
1469                                                 kspread_validity.setMinimumValue(value1);
1470                                             break;
1471                                         case 6:
1472                                             kspread_validity.setCondition(Validity::SuperiorEqual);
1473                                             if (!expression0.isNull())
1474                                                 kspread_validity.setMinimumValue(value1);
1475                                             break;
1476                                         case 7:
1477                                             if (!expression0.isNull())
1478                                                 kspread_validity.setMinimumValue(value1);
1479                                             kspread_validity.setCondition(Validity::InferiorEqual);
1480                                             break;
1481                                         default:
1482                                             qDebug() << " Error in validation Operator :" << value;
1483                                             break;
1484                                         }
1485                                     }
1486                                     break;
1487                                 case 6:
1488                                     kspread_validity.setRestriction(Validity::TextLength);
1489                                     if (validation_element.hasAttribute("Operator")) {
1490                                         const Value value1(expression0.toElement().text().toInt());
1491                                         const Value value2(expression1.toElement().text().toInt());
1492                                         int value = validation_element.attribute("Operator").toInt();
1493                                         switch (value) {
1494                                         case 0:
1495                                             kspread_validity.setCondition(Validity::Between);
1496                                             if (!expression0.isNull())
1497                                                 kspread_validity.setMinimumValue(value1);
1498                                             if (!expression1.isNull())
1499                                                 kspread_validity.setMaximumValue(value2);
1500                                             break;
1501                                         case 1:
1502                                             kspread_validity.setCondition(Validity::DifferentTo);
1503                                             if (!expression0.isNull())
1504                                                 kspread_validity.setMinimumValue(value1);
1505                                             if (!expression1.isNull())
1506                                                 kspread_validity.setMaximumValue(value2);
1507                                             break;
1508                                         case 2:
1509                                             kspread_validity.setCondition(Validity::Equal);
1510                                             if (!expression0.isNull())
1511                                                 kspread_validity.setMinimumValue(value1);
1512                                             break;
1513                                         case 3:
1514                                             kspread_validity.setCondition(Validity::Different);
1515                                             if (!expression0.isNull())
1516                                                 kspread_validity.setMinimumValue(value1);
1517                                             break;
1518                                         case 4:
1519                                             if (!expression0.isNull())
1520                                                 kspread_validity.setMinimumValue(value1);
1521                                             kspread_validity.setCondition(Validity::Superior);
1522                                             break;
1523                                         case 5:
1524                                             if (!expression0.isNull())
1525                                                 kspread_validity.setMinimumValue(value1);
1526                                             kspread_validity.setCondition(Validity::Inferior);
1527                                             break;
1528                                         case 6:
1529                                             if (!expression0.isNull())
1530                                                 kspread_validity.setMinimumValue(value1);
1531                                             kspread_validity.setCondition(Validity::SuperiorEqual);
1532                                             break;
1533                                         case 7:
1534                                             if (!expression0.isNull())
1535                                                 kspread_validity.setMinimumValue(value1);
1536                                             kspread_validity.setCondition(Validity::InferiorEqual);
1537                                             break;
1538                                         default:
1539                                             qDebug() << " Error in validation Operator :" << value;
1540                                             break;
1541                                         }
1542                                     }
1543                                     break;
1544                                 default:
1545                                     qDebug() << " Error in Type element :" << valueOp;
1546                                 }
1547 
1548                             }
1549                             //<Validation Style="0" Type="1" Operator="0" AllowBlank="true" UseDropdown="false">
1550                             //<Expression0>745</Expression0>
1551                             //<Expression1>4546</Expression1>
1552                         }
1553                     }
1554                     if (!font.isNull()) {
1555                         QDomElement font_element = font.toElement();
1556 
1557                         style.setFontFamily(font_element.text());
1558 
1559                         if (!font_element.isNull()) {
1560                             if (font_element.attribute("Italic") == "1") {
1561                                 style.setFontItalic(true);
1562                             }
1563 
1564                             if (font_element.attribute("Bold") == "1") {
1565                                 style.setFontBold(true);
1566                             }
1567 
1568                             if (font_element.hasAttribute("Underline") && (font_element.attribute("Underline") != "0")) {
1569                                 style.setFontUnderline(true);
1570                             }
1571 
1572                             if (font_element.hasAttribute("StrikeThrough") && (font_element.attribute("StrikeThrough") != "0")) {
1573                                 style.setFontStrikeOut(true);
1574                             }
1575 
1576                             if (font_element.hasAttribute("Unit")) {
1577                                 style.setFontSize(font_element.attribute("Unit").toInt());
1578                             }
1579 
1580                         }
1581                         if (!hyperlink.isNull()) {
1582                             //<HyperLink type="GnmHLinkURL" target="www.kde.org"/>
1583                             if (hyperlink.toElement().hasAttribute("type")) {
1584                                 QString linkType = hyperlink.toElement().attribute("type");
1585                                 QString target = hyperlink.toElement().attribute("target");
1586                                 QString tip = hyperlink.toElement().attribute("tip");
1587                                 if (!tip.isEmpty()) {
1588                                     kspread_cell.setUserInput(tip);
1589                                     kspread_cell.setValue(Value(tip));
1590                                 }
1591                                 if (linkType == "GnmHLinkURL") {
1592                                     if (!target.startsWith("http://"))
1593                                         target = "http://" + target;
1594                                     kspread_cell.setLink(target);
1595                                 } else if (linkType == "GnmHLinkEMail") {
1596                                     if (!target.startsWith("mailto:/"))
1597                                         target = "mailto:/" + target;
1598                                     kspread_cell.setLink(target);
1599                                 } else if (linkType == "GnmHLinkExternal") {
1600                                     if (!target.startsWith("file://"))
1601                                         target = "file://" + target;
1602 
1603                                     kspread_cell.setLink(target);
1604                                 } else if (linkType == "GnmHLinkCurWB") {
1605                                     kspread_cell.setLink(target);
1606                                 } else
1607                                     qDebug() << " linkType not defined :" << linkType;
1608                             }
1609                         }
1610                     }
1611                     kspread_cell.setStyle(style);
1612                 }
1613             }
1614             style_region = style_region.nextSibling();
1615         }
1616 
1617     }
1618 }
1619 
1620 /* NOTE: As of now everything is in a single huge function.  This is
1621          very ugly.  It should all be broken up into smaller
1622          functions, probably one for each GNUMeric section.  It kind
1623          of grew out of control.  It could probably be cleaned up in
1624          an hour or so. --PGE
1625   */
1626 
1627 
1628 KoFilter::ConversionStatus GNUMERICFilter::convert(const QByteArray & from, const QByteArray & to)
1629 {
1630     dateInit();
1631     bool bSuccess = true;
1632 
1633     qDebug() << "Entering GNUmeric Import filter.";
1634 
1635     KoDocument * document = m_chain->outputDocument();
1636     if (!document)
1637         return KoFilter::StupidError;
1638 
1639     qDebug() << "here we go..." << document->metaObject()->className() << "mimetype:" << document->mimeType();
1640 
1641     if (!qobject_cast<const Calligra::Sheets::Doc *>(document)) {    // it's safer that way :)
1642         qDebug() << "document isn't a Calligra::Sheets::Doc but a " << document->metaObject()->className();
1643         return KoFilter::NotImplemented;
1644     }
1645     if (from != "application/x-gnumeric" || to != "application/x-kspread") {
1646         qDebug() << "Invalid mimetypes " << from << " " << to;
1647         return KoFilter::NotImplemented;
1648     }
1649 
1650     qDebug() << "...still here...";
1651 
1652     // No need for a dynamic cast here, since we use Qt's moc magic
1653     Doc * ksdoc = (Doc *) document;
1654 
1655     if (ksdoc->mimeType() != "application/x-gnumeric") {
1656         qDebug() << "Invalid document mimetype " << ksdoc->mimeType();
1657         return KoFilter::NotImplemented;
1658     }
1659 
1660 
1661     QIODevice* in = new KCompressionDevice(m_chain->inputFile(), KCompressionDevice::GZip);
1662 
1663     if (!in) {
1664         qDebug() << "Cannot create device for uncompressing! Aborting!" << endl;
1665         return KoFilter::FileNotFound;
1666     }
1667 
1668     if (!in->open(QIODevice::ReadOnly)) {
1669         qDebug() << "Cannot open file for uncompressing! Aborting!" << endl;
1670         delete in;
1671         return KoFilter::FileNotFound;
1672     }
1673 
1674     QDomDocument doc;
1675     QString errorMsg;
1676     int errorLine, errorColumn;
1677     if (!doc.setContent(in, true, &errorMsg, &errorLine, &errorColumn)) {
1678         qDebug() << "Parsing error in " << from << "! Aborting!" << endl
1679         << " In line: " << errorLine << ", column: " << errorColumn << endl
1680         << " Error message: " << errorMsg << endl;
1681         in->close();
1682         return KoFilter::ParsingError;
1683     }
1684 
1685     in->close();
1686     delete in;
1687 
1688     int row, column;
1689     int value = 0;
1690     int currentTab = -1;
1691     int selectedTab = 0;
1692     Sheet * selTable = 0;
1693 
1694     QDomElement docElem = doc.documentElement();
1695     QDomElement uiData  = docElem.namedItem("UIData").toElement();
1696     if (!uiData.isNull()) {
1697         if (uiData.hasAttribute("SelectedTab")) {
1698             bool ok = false;
1699             int n = uiData.attribute("SelectedTab").toInt(&ok);
1700             if (ok) {
1701                 selectedTab = n;
1702             }
1703         }
1704     }
1705     QDomNode sheets = docElem.namedItem("Sheets");
1706     if (sheets.isNull()) {
1707         //avoid crash with new file format.
1708         //TODO allow to load new file format
1709         return KoFilter::ParsingError;
1710     }
1711     QDomNode sheet =  sheets.namedItem("Sheet");
1712 
1713     /* This sets the Document information. */
1714     set_document_info(document, &docElem);
1715 
1716     /* This sets the Document attributes */
1717     set_document_attributes(ksdoc, &docElem);
1718 
1719     /* This sets the Area Names */
1720     set_document_area_names(ksdoc, &docElem);
1721 
1722     Sheet * table;
1723     ApplicationSettings *sett = ksdoc->map()->applicationSettings();
1724 
1725     // This is a mapping of exprID to expressions.
1726 
1727     QMap<QString, char*> exprID_dict;
1728     int num = 1;
1729 
1730     while (!sheet.isNull()) {
1731         ++currentTab;
1732         table = dynamic_cast<Sheet *>(ksdoc->map()->addNewSheet());
1733 
1734         if (currentTab == selectedTab)
1735             selTable = table;
1736 
1737         QDomElement name = sheet.namedItem("Name").toElement();
1738         QDomElement sheetElement = sheet.toElement();
1739 
1740         if (!name.isNull())
1741             table->setSheetName(name.text());
1742         else
1743             table->setSheetName("Sheet" + QString::number(num));
1744 
1745         //kDebug()<<" sheetElement.hasAttribute( DisplayFormulas ) :"<<sheetElement.hasAttribute("DisplayFormulas" );
1746         QString tmp;
1747         if (sheetElement.hasAttribute("DisplayFormulas")) {
1748             tmp = sheetElement.attribute("DisplayFormulas");
1749             table->setShowFormula((tmp == "true") || (tmp == "1"));
1750         }
1751         if (sheetElement.hasAttribute("HideZero")) {
1752             tmp = sheetElement.attribute("HideZero");
1753             table->setHideZero((tmp == "true") || (tmp == "1"));
1754         }
1755         if (sheetElement.hasAttribute("HideGrid")) {
1756             tmp = sheetElement.attribute("HideGrid");
1757             table->setShowGrid((tmp == "false") || (tmp == "0"));
1758         }
1759         if (sheetElement.hasAttribute("HideColHeader")) {
1760             tmp = sheetElement.attribute("HideColHeader");
1761             sett->setShowColumnHeader((tmp == "false") || (tmp == "0"));
1762         }
1763         if (sheetElement.hasAttribute("HideRowHeader")) {
1764             tmp = sheetElement.attribute("HideRowHeader");
1765             sett->setShowRowHeader((tmp == "false") || (tmp == "0"));
1766         }
1767 
1768 
1769         setObjectInfo(&sheet, table);
1770         setColInfo(&sheet, table);
1771         setRowInfo(&sheet, table);
1772         setSelectionInfo(&sheet, table);
1773 
1774         /* handling print information */
1775         QDomNode printInfo = sheet.namedItem("PrintInformation");
1776         if (!printInfo.isNull())
1777             ParsePrintInfo(printInfo, table);
1778 
1779         qDebug() << "Reading in cells";
1780 
1781         /* CELL handling START */
1782         QDomNode cells = sheet.namedItem("Cells");
1783         QDomNode cell  = cells.namedItem("Cell");
1784         QDomNode mergedCells = sheet.namedItem("MergedRegions");
1785         QDomNode mergedRegion = mergedCells.namedItem("Merge");
1786         if (cell.isNull()) {
1787             qDebug() << "No cells";
1788         }
1789 
1790         while (!cell.isNull()) {
1791             value += 2;
1792             emit sigProgress(value);
1793 
1794             QDomElement e = cell.toElement(); // try to convert the node to an element.
1795             if (!e.isNull()) { // the node was really an element.
1796                 qDebug() << "New Cell";
1797                 QDomNode content_node = cell.namedItem("Content");
1798 
1799                 if (!content_node.isNull()) {
1800                     QDomElement content = content_node.toElement();
1801 
1802                     if (!content.isNull()) { // the node was really an element.
1803                         column = e.attribute("Col").toInt() + 1;
1804                         row    = e.attribute("Row").toInt() + 1;
1805 
1806                         QString cell_content(content.text());
1807                         //kDebug()<<"cell_content :!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<cell_content;
1808                         if (cell_content[0] == '=')
1809                             convertFormula(cell_content);
1810 
1811                         Cell kspread_cell = Cell(table, column, row);
1812                         Style style;
1813 
1814                         if (e.hasAttribute("ValueType")) {
1815                             // TODO: what is this for?
1816                             // <xsd:enumeration value="10"/> <!-- empty     -->
1817                             // <xsd:enumeration value="20"/> <!-- boolean   -->
1818                             // <xsd:enumeration value="30"/> <!-- integer   -->
1819                             // <xsd:enumeration value="40"/> <!-- float     -->
1820                             // <xsd:enumeration value="50"/> <!-- error     -->
1821                             // <xsd:enumeration value="60"/> <!-- string    -->
1822                             // <xsd:enumeration value="70"/> <!-- cellrange -->
1823                             // <xsd:enumeration value="80"/> <!-- array     -->
1824                             QString valuetype = e.attribute("ValueType");
1825                             if (valuetype == "40") { //percentage
1826                                 style.setFormatType(Format::Percentage);
1827                                 kspread_cell.setValue(Value(cell_content));
1828                             } else if (valuetype == "60") { //string
1829                                 style.setFormatType(Format::Text);
1830                                 kspread_cell.setValue(Value(cell_content));
1831                             }
1832                         }
1833 
1834                         if (e.hasAttribute("ValueFormat")) {
1835                             QString formatString = e.attribute("ValueFormat");
1836                             if (!setType(kspread_cell, formatString, cell_content))
1837                                 setText(table, row, column, cell_content, false);
1838                         } else
1839                             setText(table, row, column, cell_content, false);
1840 
1841                         if (e.hasAttribute("ExprID")) {
1842                             // QString encoded_string( Cell( table, column, row ).encodeFormula( row, column ).utf8());
1843                             QString encoded_string(Cell(table, column, row).encodeFormula().toLatin1());
1844 
1845 
1846                             char * tmp_string = (char *) malloc(strlen(encoded_string.toLatin1()));
1847                             strcpy(tmp_string, encoded_string.toLatin1());
1848 
1849                             qDebug() << encoded_string.toLatin1();
1850 
1851                             exprID_dict.insert(e.attribute("ExprID").toLower(), tmp_string);
1852 
1853                             qDebug() << exprID_dict[e.attribute(QString("ExprID").toLower())];
1854                             qDebug() << exprID_dict[QString("1")];
1855                             qDebug() << e.attribute("ExprID");
1856 
1857                         }
1858                         kspread_cell.setStyle(style);
1859                     }
1860                 } else {
1861 
1862                     column = e.attribute("Col").toInt() + 1;
1863                     row    = e.attribute("Row").toInt() + 1;
1864 
1865                     QString cell_content(e.text());
1866                     //kDebug()<<"cell_content :!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<cell_content;
1867                     if (cell_content[0] == '=')
1868                         convertFormula(cell_content);
1869 
1870                     Cell kspread_cell = Cell(table, column, row);
1871                     Style style;
1872 
1873                     if (e.hasAttribute("ValueType")) {
1874                         // TODO: Defined type of cell
1875                         //<xsd:enumeration value="10"/> <!-- empty     -->
1876                         //<xsd:enumeration value="20"/> <!-- boolean   -->
1877                         //<xsd:enumeration value="30"/> <!-- integer   -->
1878                         //<xsd:enumeration value="40"/> <!-- float     -->
1879                         //<xsd:enumeration value="50"/> <!-- error     -->
1880                         //<xsd:enumeration value="60"/> <!-- string    -->
1881                         //<xsd:enumeration value="70"/> <!-- cellrange -->
1882                         //<xsd:enumeration value="80"/> <!-- array     -->
1883                         //kspread_cell.setValue( date );
1884                         //style.setFormatType( type );
1885                         QString valuetype = e.attribute("ValueType");
1886                         if (valuetype == "40") { //percentage
1887                             style.setFormatType(Format::Percentage);
1888                             kspread_cell.setValue(Value(cell_content));
1889                         } else if (valuetype == "60") { //string
1890                             style.setFormatType(Format::Text);
1891                             kspread_cell.setValue(Value(cell_content));
1892                         }
1893 
1894                     }
1895 
1896                     if (e.hasAttribute("ValueFormat")) {
1897                         QString formatString = e.attribute("ValueFormat");
1898                         if (!setType(kspread_cell, formatString, cell_content))
1899                             setText(table, row, column, cell_content, false);
1900                     } else
1901                         setText(table, row, column, cell_content, false);
1902 
1903 
1904                     if (e.hasAttribute("ExprID")) {
1905                         column = e.attribute("Col").toInt() + 1;
1906                         row    = e.attribute("Row").toInt() + 1;
1907                         char * expr;
1908                         expr = exprID_dict[e.attribute("ExprID").toLower()];
1909                         // expr = exprID_dict[QString("1")];
1910 
1911                         qDebug() << "FOO:" << column << row;
1912                         qDebug() <<
1913                         Cell(table, column, row).decodeFormula(expr).toLatin1() << endl;
1914                         qDebug() << expr;
1915 
1916                         setText(table, row, column, Cell(table, column, row).decodeFormula(expr), false);
1917                     }
1918                     kspread_cell.setStyle(style);
1919                 }
1920             }
1921             cell = cell.nextSibling();
1922         }
1923 
1924         qDebug() << "Reading in cells done";
1925 
1926         if (mergedRegion.isNull()) {
1927             qDebug() << "No cells merged !";
1928         }
1929         while (!mergedRegion.isNull()) {
1930             QDomElement e = mergedRegion.toElement(); // try to convert the node to an element.
1931             QString cell_merge_area(e.text());
1932             const Calligra::Sheets::Region region = ksdoc->map()->regionFromName(cell_merge_area, table);
1933             //kDebug()<<"text !!! :"<<cell_merge_area<<"range :start row :"<<range.startRow ()<<" start col :"<<range.startCol ()<<" end row :"<<range.endRow ()<<" end col :"<<range.endCol ();
1934             Cell cell = Cell(table, region.firstRange().left(), region.firstRange().top());
1935             cell.mergeCells(region.firstRange().left(), region.firstRange().top(),
1936                             region.firstRange().width() - 1, region.firstRange().height() - 1);
1937             mergedRegion = mergedRegion.nextSibling();
1938         }
1939 #ifdef __GNUC__
1940 #warning "The strings in the exprID_dict have been allocated, but they have not been freed: there is a memory leak here"
1941 #endif
1942         /* exprID_dict.statistics(); */
1943 
1944         /* CELL handling STOP */
1945 
1946         /* STYLE handling START */
1947         //Laurent - 2001-12-07  deactivate this code : otherwise we
1948         //create 65535*255 cells (Styleregion is define for a area and
1949         //not for cell, so gnumeric define a style as : col start=0 col end=255
1950         //rowstart=0 rowend=255 => we create 255*255 cells
1951         //and gnumeric stocke all area and not just modify area
1952         //=> not good for Calligra Sheets.
1953         // Norbert: activated again, only cells with texts get modified, nothing else created
1954         setStyleInfo(&sheet, table);
1955 
1956         sheet = sheet.nextSibling();
1957         ++num;
1958     }
1959 
1960     if (selTable) {
1961         ksdoc->map()->loadingInfo()->setFileFormat(LoadingInfo::Gnumeric);
1962         ksdoc->map()->loadingInfo()->setInitialActiveSheet(selTable);
1963     }
1964 
1965     emit sigProgress(100);
1966     if (bSuccess)
1967         return KoFilter::OK;
1968     else
1969         return KoFilter::StupidError;
1970 }
1971 
1972 void GNUMERICFilter::setText(Calligra::Sheets::Sheet* sheet, int _row, int _column, const QString& _text,
1973                              bool asString)
1974 {
1975     Cell cell(sheet, _column, _row);
1976     if (asString) {
1977         cell.setUserInput(_text);
1978         cell.setValue(Value(_text));
1979     } else {
1980         cell.parseUserInput(_text);
1981     }
1982 }
1983 
1984 #include <gnumericimport.moc>