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>