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