Warning, file /office/calligra/filters/sheets/gnumeric/gnumericexport.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 SPDX-FileCopyrightText: 2000 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 export filter by Phillip Ezolt (phillipezolt@hotmail.com) 0009 2004 - Some updates by Tim Beaulen (tbscope@gmail.com) */ 0010 0011 #include <gnumericexport.h> 0012 0013 #include <KCompressionDevice> 0014 #include <kpluginfactory.h> 0015 0016 // Calligra 0017 #include <KoDocumentInfo.h> 0018 #include <KoFilterChain.h> 0019 #include <KoZoomHandler.h> 0020 #include <KoPart.h> 0021 #include <KoUnit.h> 0022 0023 // Calligra::Sheets 0024 #include <sheets/engine/CellBaseStorage.h> 0025 #include <sheets/engine/Localization.h> 0026 #include <sheets/engine/NamedAreaManager.h> 0027 #include <sheets/engine/ValueConverter.h> 0028 #include <sheets/engine/Validity.h> 0029 0030 #include <sheets/core/ApplicationSettings.h> 0031 #include <sheets/core/Cell.h> 0032 #include <sheets/core/ColFormatStorage.h> 0033 #include <sheets/core/DocBase.h> 0034 #include <sheets/core/HeaderFooter.h> 0035 #include <sheets/core/Map.h> 0036 #include <sheets/core/PrintSettings.h> 0037 #include <sheets/core/RowFormatStorage.h> 0038 #include <sheets/core/Sheet.h> 0039 #include <sheets/core/Style.h> 0040 0041 #include <sheets/part/Canvas.h> 0042 #include <sheets/part/View.h> 0043 0044 using namespace Calligra::Sheets; 0045 0046 K_PLUGIN_FACTORY_WITH_JSON(GNUMERICExportFactory, "calligra_filter_sheets2gnumeric.json", 0047 registerPlugin<GNUMERICExport>();) 0048 0049 GNUMERICExport::GNUMERICExport(QObject* parent, const QVariantList&) 0050 : KoFilter(parent) 0051 { 0052 isLink = false; 0053 isLinkBold = false; 0054 isLinkItalic = false; 0055 } 0056 0057 /** 0058 * This function will check if a cell has any type of border. 0059 */ 0060 bool GNUMERICExport::hasBorder(const Cell& cell, int currentcolumn, int currentrow) 0061 { 0062 Q_UNUSED(currentcolumn); 0063 Q_UNUSED(currentrow); 0064 const Style style = cell.style(); 0065 if (((style.leftBorderPen().width() != 0) && 0066 (style.leftBorderPen().style() != Qt::NoPen)) || 0067 ((style.rightBorderPen().width() != 0) && 0068 (style.rightBorderPen().style() != Qt::NoPen)) || 0069 ((style.topBorderPen().width() != 0) && 0070 (style.topBorderPen().style() != Qt::NoPen)) || 0071 ((style.bottomBorderPen().width() != 0) && 0072 (style.bottomBorderPen().style() != Qt::NoPen)) || 0073 ((style.fallDiagonalPen().width() != 0) && 0074 (style.fallDiagonalPen().style() != Qt::NoPen)) || 0075 ((style.goUpDiagonalPen().width() != 0) && 0076 (style.goUpDiagonalPen().style() != Qt::NoPen))) 0077 return true; 0078 else 0079 return false; 0080 } 0081 0082 const QString GNUMERICExport::ColorToString(int red, int green, int blue) 0083 { 0084 return QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16); 0085 } 0086 0087 QDomElement GNUMERICExport::GetBorderStyle(QDomDocument gnumeric_doc, const Cell& cell, int currentcolumn, int currentrow) 0088 { 0089 Q_UNUSED(currentcolumn); 0090 Q_UNUSED(currentrow); 0091 0092 QDomElement border_style; 0093 QDomElement border; 0094 0095 int red, green, blue; 0096 QColor color; 0097 0098 border_style = gnumeric_doc.createElement("gmr:StyleBorder"); 0099 const Style style = cell.style(); 0100 0101 if ((style.leftBorderPen().width() != 0) && 0102 (style.leftBorderPen().style() != Qt::NoPen)) { 0103 border = gnumeric_doc.createElement("gmr:Left"); 0104 border.setAttribute("Style", "1"); 0105 0106 color = style.leftBorderPen().color(); 0107 red = color.red() << 8; 0108 green = color.green() << 8; 0109 blue = color.blue() << 8; 0110 0111 border.setAttribute("Color", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0112 } else { 0113 border = gnumeric_doc.createElement("gmr:Left"); 0114 border.setAttribute("Style", "0"); 0115 } 0116 0117 border_style.appendChild(border); 0118 0119 if ((style.rightBorderPen().width() != 0) && 0120 (style.rightBorderPen().style() != Qt::NoPen)) { 0121 border = gnumeric_doc.createElement("gmr:Right"); 0122 border.setAttribute("Style", "1"); 0123 0124 color = style.rightBorderPen().color(); 0125 red = color.red() << 8; 0126 green = color.green() << 8; 0127 blue = color.blue() << 8; 0128 0129 border.setAttribute("Color", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0130 } else { 0131 border = gnumeric_doc.createElement("gmr:Right"); 0132 border.setAttribute("Style", "0"); 0133 } 0134 0135 border_style.appendChild(border); 0136 0137 if ((style.topBorderPen().width() != 0) && 0138 (style.topBorderPen().style() != Qt::NoPen)) { 0139 border = gnumeric_doc.createElement("gmr:Top"); 0140 border.setAttribute("Style", "1"); 0141 0142 color = style.topBorderPen().color(); 0143 red = color.red() << 8; 0144 green = color.green() << 8; 0145 blue = color.blue() << 8; 0146 0147 border.setAttribute("Color", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0148 } else { 0149 border = gnumeric_doc.createElement("gmr:Top"); 0150 border.setAttribute("Style", "0"); 0151 } 0152 0153 border_style.appendChild(border); 0154 0155 if ((style.bottomBorderPen().width() != 0) && 0156 (style.bottomBorderPen().style() != Qt::NoPen)) { 0157 border = gnumeric_doc.createElement("gmr:Bottom"); 0158 border.setAttribute("Style", "1"); 0159 0160 color = style.bottomBorderPen().color(); 0161 red = color.red() << 8; 0162 green = color.green() << 8; 0163 blue = color.blue() << 8; 0164 0165 border.setAttribute("Color", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0166 } else { 0167 border = gnumeric_doc.createElement("gmr:Bottom"); 0168 border.setAttribute("Style", "0"); 0169 } 0170 0171 border_style.appendChild(border); 0172 0173 if ((style.fallDiagonalPen().width() != 0) && 0174 (style.fallDiagonalPen().style() != Qt::NoPen)) { 0175 border = gnumeric_doc.createElement("gmr:Diagonal"); 0176 border.setAttribute("Style", "1"); 0177 0178 color = style.fallDiagonalPen().color(); 0179 red = color.red() << 8; 0180 green = color.green() << 8; 0181 blue = color.blue() << 8; 0182 0183 border.setAttribute("Color", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0184 } else { 0185 border = gnumeric_doc.createElement("gmr:Diagonal"); 0186 border.setAttribute("Style", "0"); 0187 } 0188 0189 border_style.appendChild(border); 0190 0191 if ((style.goUpDiagonalPen().width() != 0) && 0192 (style.goUpDiagonalPen().style() != Qt::NoPen)) { 0193 border = gnumeric_doc.createElement("gmr:Rev-Diagonal"); 0194 border.setAttribute("Style", "1"); 0195 0196 color = style.goUpDiagonalPen().color(); 0197 red = color.red() << 8; 0198 green = color.green() << 8; 0199 blue = color.blue() << 8; 0200 0201 border.setAttribute("Color", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0202 } else { 0203 border = gnumeric_doc.createElement("gmr:Rev-Diagonal"); 0204 border.setAttribute("Style", "0"); 0205 } 0206 0207 border_style.appendChild(border); 0208 0209 return border_style; 0210 } 0211 0212 QDomElement GNUMERICExport::GetValidity(QDomDocument gnumeric_doc, const Cell& cell) 0213 { 0214 ValueConverter *const converter = cell.sheet()->map()->converter(); 0215 0216 //<gmr:Validation Style="1" Type="1" Operator="7" AllowBlank="true" UseDropdown="false" Title="ghhg" Message="ghghhhjfhfghjfghj fg hjgf hj"> 0217 // <gmr:Expression0>45</gmr:Expression0> 0218 // </gmr:Validation> 0219 Validity kspread_validity = cell.validity(); 0220 QDomElement val = gnumeric_doc.createElement("gmr:Validation"); 0221 val.setAttribute("Title", kspread_validity.title()); 0222 val.setAttribute("Message", kspread_validity.message()); 0223 val.setAttribute("AllowBlank", kspread_validity.allowEmptyCell() ? "true" : "false"); 0224 if (!kspread_validity.displayMessage()) { 0225 val.setAttribute("Style", "0"); 0226 } else { 0227 switch (kspread_validity.action()) { 0228 case Validity::Stop: 0229 val.setAttribute("Style", "1"); 0230 break; 0231 case Validity::Warning: 0232 val.setAttribute("Style", "2"); 0233 break; 0234 case Validity::Information: 0235 val.setAttribute("Style", "3"); 0236 break; 0237 } 0238 } 0239 0240 switch (kspread_validity.condition()) { 0241 case Validity::None: 0242 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0243 //Nothing 0244 break; 0245 case Validity::Equal: 0246 val.setAttribute("Operator", "2"); 0247 break; 0248 case Validity::Superior: 0249 val.setAttribute("Operator", "4"); 0250 break; 0251 case Validity::Inferior: 0252 val.setAttribute("Operator", "5"); 0253 break; 0254 case Validity::SuperiorEqual: 0255 val.setAttribute("Operator", "6"); 0256 break; 0257 case Validity::InferiorEqual: 0258 val.setAttribute("Operator", "7"); 0259 break; 0260 case Validity::Between: 0261 val.setAttribute("Operator", "0"); 0262 break; 0263 case Validity::Different: 0264 val.setAttribute("Operator", "3"); 0265 break; 0266 case Validity::DifferentTo: 0267 val.setAttribute("Operator", "1"); 0268 break; 0269 } 0270 switch (kspread_validity.restriction()) { 0271 case Validity::NoRestriction: 0272 val.setAttribute("Type", "0"); 0273 break; 0274 case Validity::Number: { 0275 val.setAttribute("Type", "2"); 0276 switch (kspread_validity.condition()) { 0277 case Validity::None: 0278 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0279 //Nothing 0280 break; 0281 case Validity::Equal: 0282 case Validity::Superior: 0283 case Validity::Inferior: 0284 case Validity::SuperiorEqual: 0285 case Validity::InferiorEqual: 0286 case Validity::Different: { 0287 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0288 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0289 val.appendChild(tmp); 0290 } 0291 break; 0292 case Validity::Between: 0293 case Validity::DifferentTo: { 0294 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0295 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0296 val.appendChild(tmp); 0297 tmp = gnumeric_doc.createElement("gmr:Expression1"); 0298 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.maximumValue()).asString())); 0299 val.appendChild(tmp); 0300 } 0301 break; 0302 } 0303 0304 break; 0305 } 0306 case Validity::Text: 0307 //Not supported into gnumeric 0308 //val.setAttribute("Type", "1" ); 0309 break; 0310 case Validity::Time: 0311 val.setAttribute("Type", "5"); 0312 switch (kspread_validity.condition()) { 0313 case Validity::None: 0314 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0315 //Nothing 0316 break; 0317 case Validity::Equal: 0318 case Validity::Superior: 0319 case Validity::Inferior: 0320 case Validity::SuperiorEqual: 0321 case Validity::InferiorEqual: 0322 case Validity::Different: { 0323 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0324 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0325 val.appendChild(tmp); 0326 } 0327 break; 0328 case Validity::Between: 0329 case Validity::DifferentTo: { 0330 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0331 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0332 val.appendChild(tmp); 0333 tmp = gnumeric_doc.createElement("gmr:Expression1"); 0334 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.maximumValue()).asString())); 0335 val.appendChild(tmp); 0336 } 0337 break; 0338 } 0339 0340 break; 0341 case Validity::Date: 0342 val.setAttribute("Type", "4"); 0343 switch (kspread_validity.condition()) { 0344 case Validity::None: 0345 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0346 //Nothing 0347 break; 0348 case Validity::Equal: 0349 case Validity::Superior: 0350 case Validity::Inferior: 0351 case Validity::SuperiorEqual: 0352 case Validity::InferiorEqual: 0353 case Validity::Different: { 0354 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0355 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0356 val.appendChild(tmp); 0357 } 0358 break; 0359 case Validity::Between: 0360 case Validity::DifferentTo: { 0361 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0362 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0363 val.appendChild(tmp); 0364 tmp = gnumeric_doc.createElement("gmr:Expression1"); 0365 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.maximumValue()).asString())); 0366 val.appendChild(tmp); 0367 } 0368 break; 0369 } 0370 0371 break; 0372 case Validity::Integer: 0373 val.setAttribute("Type", "1"); 0374 switch (kspread_validity.condition()) { 0375 case Validity::None: 0376 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0377 //Nothing 0378 break; 0379 case Validity::Equal: 0380 case Validity::Superior: 0381 case Validity::Inferior: 0382 case Validity::SuperiorEqual: 0383 case Validity::InferiorEqual: 0384 case Validity::Different: { 0385 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0386 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0387 val.appendChild(tmp); 0388 } 0389 break; 0390 case Validity::Between: 0391 case Validity::DifferentTo: { 0392 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0393 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0394 val.appendChild(tmp); 0395 tmp = gnumeric_doc.createElement("gmr:Expression1"); 0396 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.maximumValue()).asString())); 0397 val.appendChild(tmp); 0398 } 0399 break; 0400 } 0401 break; 0402 case Validity::TextLength: 0403 val.setAttribute("Type", "6"); 0404 switch (kspread_validity.condition()) { 0405 case Validity::None: 0406 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0407 //Nothing 0408 break; 0409 case Validity::Equal: 0410 case Validity::Superior: 0411 case Validity::Inferior: 0412 case Validity::SuperiorEqual: 0413 case Validity::InferiorEqual: 0414 case Validity::Different: { 0415 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0416 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0417 val.appendChild(tmp); 0418 } 0419 break; 0420 case Validity::Between: 0421 case Validity::DifferentTo: { 0422 QDomElement tmp = gnumeric_doc.createElement("gmr:Expression0"); 0423 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.minimumValue()).asString())); 0424 val.appendChild(tmp); 0425 tmp = gnumeric_doc.createElement("gmr:Expression1"); 0426 tmp.appendChild(gnumeric_doc.createTextNode(converter->asString(kspread_validity.maximumValue()).asString())); 0427 val.appendChild(tmp); 0428 } 0429 break; 0430 } 0431 break; 0432 case Validity::List: 0433 val.setAttribute("Type", "3"); 0434 switch (kspread_validity.condition()) { 0435 case Validity::None: 0436 case Validity::IsTrueFormula: // FIXME: handle isTrueFormula 0437 //Nothing 0438 break; 0439 case Validity::Equal: 0440 case Validity::Superior: 0441 case Validity::Inferior: 0442 case Validity::SuperiorEqual: 0443 case Validity::InferiorEqual: 0444 case Validity::Different: 0445 break; 0446 case Validity::Between: 0447 case Validity::DifferentTo: 0448 break; 0449 } 0450 break; 0451 } 0452 0453 return val; 0454 } 0455 0456 QDomElement GNUMERICExport::GetFontStyle(QDomDocument gnumeric_doc, const Cell& cell, int currentcolumn, int currentrow) 0457 { 0458 QDomElement font_style; 0459 const Style style = cell.style(); 0460 qDebug() << " currentcolumn :" << currentcolumn << " currentrow :" << currentrow; 0461 font_style = gnumeric_doc.createElement("gmr:Font"); 0462 font_style.appendChild(gnumeric_doc.createTextNode(style.fontFamily())); 0463 0464 if (style.italic() || (isLink && isLinkItalic)) { 0465 font_style.setAttribute("Italic", "1"); 0466 } 0467 if (style.bold() || (isLink && isLinkBold)) { 0468 font_style.setAttribute("Bold", "1"); 0469 } 0470 if (style.underline()) { 0471 font_style.setAttribute("Underline", "1"); 0472 } 0473 if (style.strikeOut()) { 0474 font_style.setAttribute("StrikeThrough", "1"); 0475 } 0476 if (style.fontSize()) { 0477 font_style.setAttribute("Unit", QString::number(style.fontSize())); 0478 } 0479 0480 return font_style; 0481 } 0482 0483 QDomElement GNUMERICExport::GetLinkStyle(QDomDocument gnumeric_doc) 0484 { 0485 QDomElement link_style; 0486 0487 link_style = gnumeric_doc.createElement("gmr:HyperLink"); 0488 0489 QString path; 0490 0491 path = linkUrl; 0492 0493 if (path.section(":", 0, 0).toLower() == "http") 0494 link_style.setAttribute("type", "GnmHLinkURL"); 0495 else if (path.section(":", 0, 0).toLower() == "mailto") 0496 link_style.setAttribute("type", "GnmHLinkEMail"); 0497 else if (path.section(":", 0, 0).toLower() == "file") 0498 link_style.setAttribute("type", "GnmHLinkExternal"); 0499 else if (path.left(5).toLower() == "sheet") 0500 link_style.setAttribute("type", "GnmHLinkCurWB"); 0501 else 0502 link_style.setAttribute("type", ""); 0503 0504 link_style.setAttribute("target", path); 0505 0506 // Calligra Sheets doesn't support link tips. 0507 link_style.setAttribute("tip", ""); 0508 0509 return link_style; 0510 } 0511 0512 QDomElement GNUMERICExport::GetCellStyle(QDomDocument gnumeric_doc, const Cell& cell, int currentcolumn, int currentrow) 0513 { 0514 QDomElement cell_style; 0515 0516 cell_style = gnumeric_doc.createElement("gmr:Style"); 0517 0518 int red, green, blue; 0519 0520 const Style style = cell.style(); 0521 QColor bgColor = style.backgroundColor(); 0522 if (bgColor.isValid()) { 0523 red = bgColor.red() << 8; 0524 green = bgColor.green() << 8; 0525 blue = bgColor.blue() << 8; 0526 } else { 0527 // Let's use white default for background 0528 red = 0xffff; 0529 green = 0xffff; 0530 blue = 0xffff; 0531 } 0532 0533 switch (style.backgroundBrush().style()) { 0534 case Qt::NoBrush: 0535 cell_style.setAttribute("Shade", "0"); 0536 break; 0537 case Qt::SolidPattern: 0538 // 100% 0539 cell_style.setAttribute("Shade", "1"); 0540 break; 0541 case Qt::Dense1Pattern: 0542 // 87.5% 0543 cell_style.setAttribute("Shade", "25"); 0544 break; 0545 case Qt::Dense2Pattern: 0546 // 75% 0547 cell_style.setAttribute("Shade", "2"); 0548 break; 0549 case Qt::Dense3Pattern: 0550 // 62.5% 0551 // Not supported by GNumeric 0552 // Fall back to 50% 0553 cell_style.setAttribute("Shade", "3"); 0554 break; 0555 case Qt::Dense4Pattern: 0556 // 50% 0557 cell_style.setAttribute("Shade", "3"); 0558 break; 0559 case Qt::Dense5Pattern: 0560 // 25% 0561 cell_style.setAttribute("Shade", "4"); 0562 break; 0563 case Qt::Dense6Pattern: 0564 // 12.5% 0565 cell_style.setAttribute("Shade", "5"); 0566 break; 0567 case Qt::Dense7Pattern: 0568 // 6.25% 0569 cell_style.setAttribute("Shade", "6"); 0570 break; 0571 case Qt::HorPattern: 0572 cell_style.setAttribute("Shade", "13"); 0573 break; 0574 case Qt::VerPattern: 0575 cell_style.setAttribute("Shade", "14"); 0576 break; 0577 case Qt::CrossPattern: 0578 cell_style.setAttribute("Shade", "17"); 0579 break; 0580 case Qt::BDiagPattern: 0581 cell_style.setAttribute("Shade", "16"); 0582 break; 0583 case Qt::FDiagPattern: 0584 cell_style.setAttribute("Shade", "15"); 0585 break; 0586 case Qt::DiagCrossPattern: 0587 cell_style.setAttribute("Shade", "18"); 0588 break; 0589 case Qt::TexturePattern: 0590 default: 0591 // Not supported by Gnumeric 0592 cell_style.setAttribute("Shade", "0"); 0593 break; 0594 } 0595 0596 cell_style.setAttribute("Back", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0597 0598 0599 QColor textColor = style.fontColor(); 0600 red = textColor.red() << 8; 0601 green = textColor.green() << 8; 0602 blue = textColor.blue() << 8; 0603 0604 cell_style.setAttribute("Fore", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0605 0606 if (style.halign() == Style::HAlignUndefined) { 0607 cell_style.setAttribute("HAlign", "1"); 0608 } else if (style.halign() == Style::Left) { 0609 cell_style.setAttribute("HAlign", "2"); 0610 } else if (style.halign() == Style::Right) { 0611 cell_style.setAttribute("HAlign", "4"); 0612 } else if (style.halign() == Style::Center) { 0613 cell_style.setAttribute("HAlign", "8"); 0614 } 0615 0616 if (style.valign() == Style::Top) { 0617 cell_style.setAttribute("VAlign", "1"); 0618 } else if (style.valign() == Style::Bottom) { 0619 cell_style.setAttribute("VAlign", "2"); 0620 } else if (style.valign() == Style::Middle) { 0621 cell_style.setAttribute("VAlign", "4"); 0622 } 0623 0624 if (style.wrapText()) 0625 cell_style.setAttribute("WrapText", "1"); 0626 else 0627 cell_style.setAttribute("WrapText", "0"); 0628 0629 // ShrinkToFit not supported by Calligra Sheets (?) 0630 cell_style.setAttribute("ShrinkToFit", "0"); 0631 0632 // I'm not sure about the rotation values. 0633 // I never got it to work in GNumeric. 0634 cell_style.setAttribute("Rotation", QString::number(-1*style.angle())); 0635 0636 // The indentation in GNumeric is an integer value. In Calligra Sheets, it's a double. 0637 // Save the double anyway, makes it even better when importing the document back in Calligra Sheets. 0638 // TODO verify if it's correct, in import we "* 10.0" 0639 cell_style.setAttribute("Indent", QString::number(style.indentation())); 0640 0641 cell_style.setAttribute("Locked", QString::number(!style.notProtected())); 0642 0643 // A Calligra Sheets cell can have two options to hide: only formula hidden, or everything hidden. 0644 // I only consider a cell with everything hidden as hidden. 0645 // Gnumeric hides everything or nothing. 0646 cell_style.setAttribute("Hidden", QString::number(style.hideAll())); 0647 0648 QColor patColor = style.backgroundBrush().color(); 0649 red = patColor.red() << 8; 0650 green = patColor.green() << 8; 0651 blue = patColor.blue() << 8; 0652 0653 cell_style.setAttribute("PatternColor", QString::number(red, 16) + ':' + QString::number(green, 16) + ':' + QString::number(blue, 16)); 0654 0655 if (isLink) 0656 cell_style.appendChild(GetLinkStyle(gnumeric_doc)); 0657 0658 cell_style.appendChild(GetFontStyle(gnumeric_doc, cell, currentcolumn, currentrow)); 0659 0660 if (!cell.validity().isEmpty()) { 0661 cell_style.appendChild(GetValidity(gnumeric_doc, cell)); 0662 } 0663 0664 QString stringFormat; 0665 0666 Currency currency; 0667 0668 switch (style.formatType()) { 0669 case Format::Generic: 0670 stringFormat = "General"; 0671 break; 0672 case Format::Number: 0673 stringFormat = "0.00"; 0674 break; 0675 case Format::Text: 0676 stringFormat = "General"; 0677 break; 0678 case Format::Money: 0679 0680 if (!style.hasAttribute(Style::CurrencyFormat)) { 0681 stringFormat = "0.00"; 0682 break; 0683 } 0684 currency = style.currency(); 0685 0686 if (currency.code().isEmpty()) 0687 stringFormat = "0.00"; 0688 else if (currency.code() == "$") 0689 stringFormat = "$0.00"; 0690 else if (currency.code() == QString::fromUtf8("€")) 0691 stringFormat = "[$€-2]0.00"; 0692 else if (currency.code() == QString::fromUtf8("£")) 0693 stringFormat = "£0.00"; 0694 else if (currency.code() == QString::fromUtf8("¥")) 0695 stringFormat = "¥0.00"; 0696 else 0697 stringFormat = "[$" + currency.code() + "]0.00"; 0698 0699 break; 0700 case Format::Percentage: 0701 stringFormat = "0.00%"; 0702 break; 0703 case Format::Scientific: 0704 stringFormat = "0.00E+00"; 0705 break; 0706 case Format::fraction_half: 0707 stringFormat = "# ?/2"; 0708 break; 0709 case Format::fraction_quarter: 0710 stringFormat = "# ?/4"; 0711 break; 0712 case Format::fraction_eighth: 0713 stringFormat = "# ?/8"; 0714 break; 0715 case Format::fraction_sixteenth: 0716 stringFormat = "# ?/16"; 0717 break; 0718 case Format::fraction_tenth: 0719 stringFormat = "# ?/10"; 0720 break; 0721 case Format::fraction_hundredth: 0722 stringFormat = "# ?/100"; 0723 break; 0724 case Format::fraction_one_digit: 0725 stringFormat = "# ?/?"; 0726 break; 0727 case Format::fraction_two_digits: 0728 stringFormat = "# ?\?/?\?"; 0729 break; 0730 case Format::fraction_three_digits: 0731 stringFormat = "# ?\?\?/?\?\?"; 0732 break; 0733 case Format::Custom: 0734 stringFormat = style.customFormat(); 0735 break; 0736 default: 0737 if (Format::isDate(style.formatType())) { 0738 cell.locale()->dateFormat(style.formatType()); 0739 } else if (Format::isTime(style.formatType())) { 0740 cell.locale()->timeFormat(style.formatType()); 0741 } else { 0742 // This is a required parameter, so let's write a sane default 0743 qWarning() << "Unhandled Format value, setting 'General' as default: " << style.formatType(); 0744 stringFormat = "General"; 0745 } 0746 break; 0747 } 0748 cell_style.setAttribute("Format", stringFormat); 0749 0750 if (hasBorder(cell, currentcolumn, currentrow)) 0751 cell_style.appendChild(GetBorderStyle(gnumeric_doc, cell, currentcolumn, currentrow)); 0752 0753 return cell_style; 0754 } 0755 0756 0757 void GNUMERICExport::addAttributeItem(QDomDocument gnumeric_doc, QDomElement attributes, const QString& type, const QString& name, bool value) 0758 { 0759 QDomElement gmr_attribute, gmr_type, gmr_name, gmr_value; 0760 0761 gmr_attribute = gnumeric_doc.createElement("gmr:Attribute"); 0762 attributes.appendChild(gmr_attribute); 0763 0764 gmr_type = gnumeric_doc.createElement("gmr:type"); 0765 gmr_type.appendChild(gnumeric_doc.createTextNode(type)); 0766 gmr_attribute.appendChild(gmr_type); 0767 0768 gmr_name = gnumeric_doc.createElement("gmr:name"); 0769 gmr_name.appendChild(gnumeric_doc.createTextNode(name)); 0770 gmr_attribute.appendChild(gmr_name); 0771 0772 QString txtValue; 0773 if (value) 0774 txtValue = "true"; 0775 else 0776 txtValue = "false"; 0777 0778 gmr_value = gnumeric_doc.createElement("gmr:value"); 0779 gmr_value.appendChild(gnumeric_doc.createTextNode(txtValue)); 0780 gmr_attribute.appendChild(gmr_value); 0781 } 0782 0783 void GNUMERICExport::addSummaryItem(QDomDocument gnumeric_doc, QDomElement summary, const QString& name, const QString& value) 0784 { 0785 if (value.isEmpty()) 0786 return; 0787 QDomElement gmr_item, gmr_name, gmr_val_string; 0788 0789 gmr_item = gnumeric_doc.createElement("gmr:Item"); 0790 summary.appendChild(gmr_item); 0791 0792 gmr_name = gnumeric_doc.createElement("gmr:name"); 0793 gmr_name.appendChild(gnumeric_doc.createTextNode(name)); 0794 gmr_item.appendChild(gmr_name); 0795 0796 gmr_val_string = gnumeric_doc.createElement("gmr:val-string"); 0797 gmr_val_string.appendChild(gnumeric_doc.createTextNode(value)); 0798 gmr_item.appendChild(gmr_val_string); 0799 } 0800 0801 // The reason why we use the KoDocument* approach and not the QDomDocument 0802 // approach is because we don't want to export formulas but values ! 0803 KoFilter::ConversionStatus GNUMERICExport::convert(const QByteArray& from, const QByteArray& to) 0804 { 0805 qDebug() << "Exporting GNUmeric"; 0806 0807 QDomDocument gnumeric_doc = QDomDocument(); 0808 0809 KoDocument* document = m_chain->inputDocument(); 0810 0811 if (!document) 0812 return KoFilter::StupidError; 0813 0814 if (!qobject_cast<const Calligra::Sheets::DocBase *>(document)) { // it's safer that way :) 0815 qWarning() << "document isn't a Calligra::Sheets::DocBase but a " << document->metaObject()->className(); 0816 return KoFilter::NotImplemented; 0817 } 0818 if (to != "application/x-gnumeric" || from != "application/x-kspread") { 0819 qWarning() << "Invalid mimetypes " << to << " " << from; 0820 return KoFilter::NotImplemented; 0821 } 0822 0823 DocBase* ksdoc = dynamic_cast<DocBase*>(document); 0824 0825 if (ksdoc->mimeType() != "application/x-kspread") { 0826 qWarning() << "Invalid document mimetype " << ksdoc->mimeType(); 0827 return KoFilter::NotImplemented; 0828 } 0829 0830 /* This could be Made into a function */ 0831 0832 gnumeric_doc.appendChild(gnumeric_doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"")); 0833 0834 QDomElement workbook = gnumeric_doc.createElement("gmr:Workbook"); 0835 workbook.setAttribute("xmlns:gmr", "http://www.gnumeric.org/v10.dtd"); 0836 workbook.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 0837 workbook.setAttribute("xmlns:schemaLocation", "http://www.gnumeric.org/v8.xsd"); 0838 gnumeric_doc.appendChild(workbook); 0839 0840 /* End Made into a function */ 0841 0842 QDomElement sheets, sheet, tmp, cells, selections, cols, rows, styles, merged, margins, topMargin, leftMargin, bottomMargin, rightMargin, orientation, paper, header, footer, customSize, cellComment, objects, repeatColumns, repeatRows; 0843 0844 KoDocumentInfo *DocumentInfo = document->documentInfo(); 0845 0846 /* 0847 * Attributes 0848 */ 0849 QDomElement attributes = gnumeric_doc.createElement("gmr:Attributes"); 0850 workbook.appendChild(attributes); 0851 0852 Map *map = ksdoc->map(); 0853 ApplicationSettings *appsett = map->applicationSettings(); 0854 addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_horizontal_scrollbar", appsett->showHorizontalScrollBar()); 0855 addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_vertical_scrollbar", appsett->showVerticalScrollBar()); 0856 addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_notebook_tabs", appsett->showTabBar()); 0857 if (appsett->completionMode() == KCompletion::CompletionAuto) 0858 addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::do_auto_completion", "true"); 0859 else 0860 addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::do_auto_completion", "false"); 0861 addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::is_protected", map->isProtected()); 0862 0863 /* 0864 * Document summary 0865 */ 0866 QDomElement summary = gnumeric_doc.createElement("gmr:Summary"); 0867 workbook.appendChild(summary); 0868 0869 addSummaryItem(gnumeric_doc, summary, "title", DocumentInfo->aboutInfo("title")); 0870 addSummaryItem(gnumeric_doc, summary, "company", DocumentInfo->authorInfo("company")); 0871 addSummaryItem(gnumeric_doc, summary, "author", DocumentInfo->authorInfo("creator")); 0872 addSummaryItem(gnumeric_doc, summary, "comments", DocumentInfo->aboutInfo("comments")); 0873 addSummaryItem(gnumeric_doc, summary, "keywords", DocumentInfo->aboutInfo("keyword")); 0874 0875 addSummaryItem(gnumeric_doc, summary, "application", "KSpread"); 0876 0877 /* 0878 * Sheet name index (necessary for the gnumeric xml_sax importer) 0879 */ 0880 QDomElement sheetNameIndex = gnumeric_doc.createElement("gmr:SheetNameIndex"); 0881 workbook.appendChild(sheetNameIndex); 0882 0883 for(SheetBase* table : map->sheetList()) { 0884 QDomElement sheetName = gnumeric_doc.createElement("gmr:SheetName"); 0885 sheetName.appendChild(gnumeric_doc.createTextNode(table->sheetName())); 0886 sheetNameIndex.appendChild(sheetName); 0887 } 0888 0889 /* 0890 * Area Names 0891 */ 0892 /* 0893 <gmr:Names> 0894 <gmr:Name> 0895 <gmr:name>test</gmr:name> 0896 <gmr:value>Sheet2!$A$2:$D$10</gmr:value> 0897 <gmr:position>A1</gmr:position> 0898 </gmr:Name> 0899 <gmr:Name> 0900 <gmr:name>voiture</gmr:name> 0901 <gmr:value>Sheet2!$A$2:$D$8</gmr:value> 0902 <gmr:position>A1</gmr:position> 0903 </gmr:Name> 0904 </gmr:Names> 0905 */ 0906 const QList<QString> namedAreas = map->namedAreaManager()->areaNames(); 0907 if (namedAreas.count() > 0) { 0908 SheetBase* sheet = 0; 0909 QRect range; 0910 QDomElement areaNames = gnumeric_doc.createElement("gmr:Names"); 0911 for (int i = 0; i < namedAreas.count(); ++i) { 0912 sheet = map->namedAreaManager()->sheet(namedAreas[i]); 0913 if (!sheet) 0914 continue; 0915 range = map->namedAreaManager()->namedArea(namedAreas[i]).firstRange(); 0916 QDomElement areaName = gnumeric_doc.createElement("gmr:Name"); 0917 QDomElement areaNameElement = gnumeric_doc.createElement("gmr:name"); 0918 areaNameElement.appendChild(gnumeric_doc.createTextNode(namedAreas[i])); 0919 areaName.appendChild(areaNameElement); 0920 QDomElement areaNameValue = gnumeric_doc.createElement("gmr:value"); 0921 areaNameValue.appendChild(gnumeric_doc.createTextNode(convertRefToRange(sheet->sheetName(), range))); 0922 areaName.appendChild(areaNameValue); 0923 areaNames.appendChild(areaName); 0924 //TODO <gmr:position>A1</gmr:position> I don't know what is it. 0925 } 0926 workbook.appendChild(areaNames); 0927 } 0928 0929 0930 /* 0931 * Sheets 0932 */ 0933 sheets = gnumeric_doc.createElement("gmr:Sheets"); 0934 workbook.appendChild(sheets); 0935 0936 QString str; 0937 0938 View *view = ksdoc->documentPart()->views().isEmpty() ? 0 : static_cast<View*>(ksdoc->documentPart()->views().first()); 0939 Canvas * canvas = 0L; 0940 QString activeTableName; 0941 if (view) { 0942 canvas = view->canvasWidget(); 0943 activeTableName = canvas->activeSheet()->sheetName(); 0944 } 0945 int i = 0; 0946 int indexActiveTable = 0; 0947 for(SheetBase* btable : map->sheetList()) { 0948 Sheet *table = dynamic_cast<Sheet *>(btable); 0949 if (table->printSettings()->pageLayout().format == KoPageFormat::CustomSize) { 0950 customSize = gnumeric_doc.createElement("gmr:Geometry"); 0951 customSize.setAttribute("Width", QString::number(POINT_TO_MM(table->printSettings()->pageLayout().width))); 0952 customSize.setAttribute("Height", QString::number(POINT_TO_MM(table->printSettings()->pageLayout().width))); 0953 sheets.appendChild(customSize); 0954 //<gmr:Geometry Width="768" Height="365"/> 0955 } 0956 0957 sheet = gnumeric_doc.createElement("gmr:Sheet"); 0958 sheets.appendChild(sheet); 0959 0960 sheet.setAttribute("DisplayFormulas", table->getShowFormula() ? "true" : "false"); 0961 sheet.setAttribute("HideZero", table->getHideZero() ? "true" : "false"); 0962 sheet.setAttribute("HideGrid", !table->getShowGrid() ? "true" : "false"); 0963 sheet.setAttribute("HideColHeader", (!appsett->showColumnHeader() ? "true" : "false")); 0964 sheet.setAttribute("HideRowHeader", (!appsett->showRowHeader() ? "true" : "false")); 0965 /* Not available in Calligra Sheets ? 0966 * sheet.setAttribute("DisplayOutlines", "true"); 0967 * sheet.setAttribute("OutlineSymbolsBelow", "true"); 0968 * sheet.setAttribute("OutlineSymbolsRight", "true"); 0969 * sheet.setAttribute("TabColor", ""); 0970 * sheet.setAttribute("TabTextColor", ""); 0971 */ 0972 0973 tmp = gnumeric_doc.createElement("gmr:Name"); 0974 if (table->sheetName() == activeTableName) 0975 indexActiveTable = i; 0976 0977 tmp.appendChild(gnumeric_doc.createTextNode(table->sheetName())); 0978 0979 sheet.appendChild(tmp); 0980 0981 tmp = gnumeric_doc.createElement("gmr:MaxCol"); 0982 tmp.appendChild(gnumeric_doc.createTextNode(QString::number(table->cellStorage()->columns()))); 0983 sheet.appendChild(tmp); 0984 0985 tmp = gnumeric_doc.createElement("gmr:MaxRow"); 0986 0987 tmp.appendChild(gnumeric_doc.createTextNode(QString::number(table->cellStorage()->rows()))); 0988 sheet.appendChild(tmp); 0989 0990 // Zoom value doesn't appear to be correct 0991 // Calligra Sheets 200% gives zoom() = 2.5, this in GNumeric = 250% 0992 tmp = gnumeric_doc.createElement("gmr:Zoom"); 0993 if (view) 0994 tmp.appendChild(gnumeric_doc.createTextNode(QString::number(view->zoomHandler()->zoom()))); 0995 else 0996 tmp.appendChild(gnumeric_doc.createTextNode("1.0")); 0997 sheet.appendChild(tmp); 0998 0999 //Print Info 1000 tmp = gnumeric_doc.createElement("gmr:PrintInformation"); 1001 margins = gnumeric_doc.createElement("gmr:Margins"); 1002 1003 topMargin = gnumeric_doc.createElement("gmr:top"); 1004 topMargin.setAttribute("Points", QString::number(table->printSettings()->pageLayout().topMargin)); 1005 topMargin.setAttribute("PrefUnit", "mm"); 1006 margins.appendChild(topMargin); 1007 1008 bottomMargin = gnumeric_doc.createElement("gmr:bottom"); 1009 bottomMargin.setAttribute("Points", QString::number(table->printSettings()->pageLayout().bottomMargin)); 1010 bottomMargin.setAttribute("PrefUnit", "mm"); 1011 margins.appendChild(bottomMargin); 1012 1013 leftMargin = gnumeric_doc.createElement("gmr:left"); 1014 leftMargin.setAttribute("Points", QString::number(table->printSettings()->pageLayout().leftMargin)); 1015 leftMargin.setAttribute("PrefUnit", "mm"); 1016 margins.appendChild(leftMargin); 1017 1018 rightMargin = gnumeric_doc.createElement("gmr:right"); 1019 rightMargin.setAttribute("Points", QString::number(table->printSettings()->pageLayout().rightMargin)); 1020 rightMargin.setAttribute("PrefUnit", "mm"); 1021 margins.appendChild(rightMargin); 1022 1023 tmp.appendChild(margins); 1024 sheet.appendChild(tmp); 1025 1026 orientation = gnumeric_doc.createElement("gmr:orientation"); 1027 QString orientString = table->printSettings()->pageLayout().orientation == KoPageFormat::Landscape ? "landscape" : "portrait"; 1028 orientation.appendChild(gnumeric_doc.createTextNode(orientString)); 1029 tmp.appendChild(orientation); 1030 1031 //TODO for future 1032 //<gmr:repeat_top value="A1:IV5"/> 1033 //<gmr:repeat_left value="B1:D65536"/> 1034 1035 int _tmpRepeatColumnStart = table->printSettings()->repeatedColumns().first; 1036 int _tmpRepeatColumnEnd = table->printSettings()->repeatedColumns().second; 1037 if (_tmpRepeatColumnStart != 0) { 1038 repeatColumns = gnumeric_doc.createElement("gmr:repeat_left"); 1039 QString value = Cell::columnName(_tmpRepeatColumnStart) + "1:" + Cell::columnName(_tmpRepeatColumnEnd) + "65536"; 1040 repeatColumns.setAttribute("value", value); 1041 tmp.appendChild(repeatColumns); 1042 } 1043 int _tmpRepeatRowStart = table->printSettings()->repeatedRows().first; 1044 int _tmpRepeatRowEnd = table->printSettings()->repeatedRows().second; 1045 if (_tmpRepeatRowStart != 0) { 1046 repeatRows = gnumeric_doc.createElement("gmr:repeat_top"); 1047 QString value = 'A' + QString::number(_tmpRepeatRowStart) + ":IV" + QString::number(_tmpRepeatRowEnd); 1048 repeatRows.setAttribute("value", value); 1049 tmp.appendChild(repeatRows); 1050 } 1051 1052 const HeaderFooter *const headerFooter = table->headerFooter(); 1053 header = gnumeric_doc.createElement("gmr:Header"); 1054 header.setAttribute("Left", convertVariable(headerFooter->headLeft())); 1055 header.setAttribute("Middle", convertVariable(headerFooter->headMid())); 1056 header.setAttribute("Right", convertVariable(headerFooter->headRight())); 1057 tmp.appendChild(header); 1058 1059 footer = gnumeric_doc.createElement("gmr:Footer"); 1060 footer.setAttribute("Left", convertVariable(headerFooter->footLeft())); 1061 footer.setAttribute("Middle", convertVariable(headerFooter->footMid())); 1062 footer.setAttribute("Right", convertVariable(headerFooter->footRight())); 1063 tmp.appendChild(footer); 1064 1065 paper = gnumeric_doc.createElement("gmr:paper"); 1066 paper.appendChild(gnumeric_doc.createTextNode(table->printSettings()->paperFormatString())); 1067 tmp.appendChild(paper); 1068 1069 styles = gnumeric_doc.createElement("gmr:Styles"); 1070 sheet.appendChild(styles); 1071 1072 cells = gnumeric_doc.createElement("gmr:Cells"); 1073 sheet.appendChild(cells); 1074 1075 objects = gnumeric_doc.createElement("gmr:Objects"); 1076 sheet.appendChild(objects); 1077 1078 merged = gnumeric_doc.createElement("gmr:MergedRegions"); 1079 bool mergedCells = false; // if there are no merged cells in this sheet, don't write an 1080 // empty mergedRegions to the file. 1081 // So, depending on the value of mergedCells, 1082 // the merged dom element is added or not. 1083 1084 cols = gnumeric_doc.createElement("gmr:Cols"); 1085 sheet.appendChild(cols); 1086 1087 rows = gnumeric_doc.createElement("gmr:Rows"); 1088 sheet.appendChild(rows); 1089 1090 /* 1091 selections = gnumeric_doc.createElement("gmr:Selections"); 1092 sheet.appendChild(selections); 1093 */ 1094 // Ah ah ah - the document is const, but the map and table aren't. Safety: 0. 1095 // Either we get hold of Sheet::m_dctCells and apply the old method below 1096 // (for sorting) or, cleaner and already sorted, we use Sheet's API 1097 // (slower probably, though) 1098 int iMaxColumn = table->cellStorage()->columns(); 1099 int iMaxRow = table->cellStorage()->rows(); 1100 1101 // this is just a bad approximation which fails for documents with less than 50 rows, but 1102 // we don't need any progress stuff there anyway :) (Werner) 1103 int value = 0; 1104 int step = iMaxRow > 50 ? iMaxRow / 50 : 1; 1105 int i = 1; 1106 1107 /* Save selection info. */ 1108 1109 /* can't save selection anymore -- part of the view, not table */ 1110 /* 1111 QDomElement selection = gnumeric_doc.createElement("gmr:Selection"); 1112 QRect table_selection(table->selection()); 1113 1114 selections.appendChild(selection); 1115 */ 1116 /* <gmr:Selection startCol="3" startRow="2" endCol="3" endRow="2"/>*/ 1117 /* 1118 selection.setAttribute("startCol", QString::number(table_selection.left()-1)); 1119 selection.setAttribute("startRow", QString::number(table_selection.top()-1)); 1120 1121 selection.setAttribute("endCol", QString::number(table_selection.right()-1)); 1122 selection.setAttribute("endRow", QString::number(table_selection.bottom()-1)); 1123 */ 1124 /* End selection info. */ 1125 1126 1127 /* Start COLS */ 1128 for (int col = 1; col <= table->columnFormats()->lastNonDefaultCol(); ++col) { 1129 int lastCol; 1130 if (table->columnFormats()->isDefaultCol(col, &lastCol)) { 1131 col = lastCol; 1132 continue; 1133 } 1134 1135 QDomElement colinfo = gnumeric_doc.createElement("gmr:ColInfo"); 1136 cols.appendChild(colinfo); 1137 colinfo.setAttribute("No", QString::number(col - 1)); 1138 colinfo.setAttribute("Hidden", QString::number(table->columnFormats()->isHidden(col))); 1139 colinfo.setAttribute("Unit", QString::number(table->columnFormats()->colWidth(col))); 1140 } 1141 1142 /* End COLS */ 1143 1144 // <gmr:ColInfo No="1" Unit="96.75" MarginA="2" MarginB="2" HardSize="-1" Hidden="0"/> 1145 1146 /* Start ROWS */ 1147 for (int row = 1; row <= table->rowFormats()->lastNonDefaultRow(); ++row) { 1148 int lastRow; 1149 if (table->rowFormats()->isDefaultRow(row, &lastRow)) { 1150 row = lastRow; 1151 continue; 1152 } 1153 QDomElement rowinfo = gnumeric_doc.createElement("gmr:RowInfo"); 1154 rows.appendChild(rowinfo); 1155 rowinfo.setAttribute("No", QString::number(row - 1)); 1156 rowinfo.setAttribute("Hidden", QString::number(table->rowFormats()->isHidden(row))); 1157 rowinfo.setAttribute("Unit", QString::number(table->rowFormats()->rowHeight(row))); 1158 } 1159 1160 /* End ROWS */ 1161 1162 //rl->setHeight 1163 // colinfo.info(); 1164 /* 1165 <gmr:ColInfo No="1" Unit="96.75" MarginA="2" MarginB="2" HardSize="-1" Hidden="0"/> 1166 <gmr:ColInfo No="3" Unit="113.25" MarginA="2" MarginB="2" HardSize="-1" 1167 Hidden="0"/> 1168 */ 1169 1170 /* End COLS */ 1171 1172 for (int currentrow = 1; currentrow <= iMaxRow; ++currentrow, ++i) { 1173 if (i > step) { 1174 value += 2; 1175 emit sigProgress(value); 1176 i = 0; 1177 } 1178 1179 for (int currentcolumn = 1; currentcolumn <= iMaxColumn; currentcolumn++) { 1180 QDomElement cell_contents; 1181 Cell cell(table, currentcolumn, currentrow); 1182 1183 QString text; 1184 QDomDocument domLink; 1185 QDomElement domRoot; 1186 QDomNodeList childNodes; 1187 1188 if (!cell.isDefault() && !cell.isEmpty()) { 1189 if (cell.isFormula()) { 1190 QString tmp = cell.userInput(); 1191 if (tmp.contains("==")) 1192 tmp.replace("==", "="); 1193 text = tmp; 1194 isLink = false; 1195 } else if (!cell.link().isEmpty()) { 1196 isLink = true; 1197 isLinkBold = false; 1198 isLinkItalic = false; 1199 //TODO FIXME 1200 linkUrl = cell.link(); 1201 linkText = cell.userInput(); 1202 1203 } else { 1204 text = cell.userInput(); 1205 isLink = false; 1206 } 1207 #if 0 1208 switch (cell.content()) { 1209 case Cell::Text: 1210 text = cell.userInput(); 1211 isLink = false; 1212 break; 1213 case Cell::RichText: 1214 // hyperlinks 1215 // Extract the cell text 1216 isLink = true; 1217 isLinkBold = false; 1218 isLinkItalic = false; 1219 domLink.setContent(cell.userInput().section("!", 1, 1)); 1220 1221 domNode = domLink.firstChild(); 1222 domRoot = domNode.toElement(); 1223 text = domNode.toElement().text(); 1224 1225 while (!domNode.isNull()) { 1226 QString style; 1227 style = domNode.toElement().tagName(); 1228 1229 if (style == "b") 1230 isLinkBold = true; 1231 1232 if (style == "i") 1233 isLinkItalic = true; 1234 1235 domNode = domNode.firstChild(); 1236 } 1237 1238 //qDebug() <<"---> link, text =" << text; 1239 1240 linkUrl = domRoot.attribute("href"); 1241 linkText = text; 1242 1243 break; 1244 case Cell::VisualFormula: 1245 isLink = false; 1246 text = cell.userInput(); // untested 1247 break; 1248 case Cell::Formula: 1249 isLink = false; 1250 QString tmp = cell.userInput(); 1251 if (tmp == "==") 1252 tmp = replace("==", "="); 1253 /* cell.calc( true ); // Incredible, cells are not calculated if the document was just opened text = cell.valueString(); */ 1254 text = tmp; 1255 break; 1256 } 1257 #endif 1258 } 1259 1260 if (!cell.isDefault()) { 1261 1262 // Check if the cell is merged 1263 // Only cells with content are interesting? 1264 // Otherwise it can take a while to parse a large sheet 1265 1266 if (cell.doesMergeCells()) { 1267 // The cell is forced to occupy other cells 1268 QDomElement merge = gnumeric_doc.createElement("gmr:Merge"); 1269 1270 // Set up the range 1271 QString fromCol, toCol, fromRow, toRow; 1272 fromCol = cell.columnName(currentcolumn); 1273 fromRow = QString::number(currentrow); 1274 toCol = cell.columnName(currentcolumn + cell.mergedXCells()); 1275 toRow = QString::number(currentrow + cell.mergedYCells()); 1276 1277 merge.appendChild(gnumeric_doc.createTextNode(fromCol + fromRow + ':' + toCol + toRow)); 1278 mergedCells = true; 1279 merged.appendChild(merge); 1280 } 1281 // --- 1282 if (!cell.comment().isEmpty()) { 1283 //<gmr:CellComment Author="" Text="cvbcvbxcvb cb xc vbxcv " ObjectBound="A1" ObjectOffset="0 0 0 0" ObjectAnchorType="17 16 17 16" Direction="17"/> 1284 cellComment = gnumeric_doc.createElement("gmr:CellComment"); 1285 cellComment.setAttribute("Text", cell.comment()); 1286 QString sCell = QString("%1%2").arg(Cell::columnName(currentcolumn)).arg(currentrow); 1287 1288 cellComment.setAttribute("ObjectBound", sCell); 1289 objects.appendChild(cellComment); 1290 1291 } 1292 QDomElement gnumeric_cell = gnumeric_doc.createElement("gmr:Cell"); 1293 QDomElement cell_style; 1294 1295 QDomElement style_region = gnumeric_doc.createElement("gmr:StyleRegion"); 1296 1297 cells.appendChild(gnumeric_cell); 1298 1299 gnumeric_cell.setAttribute("Col", QString::number(currentcolumn - 1)); 1300 gnumeric_cell.setAttribute("Row", QString::number(currentrow - 1)); 1301 1302 /* Right now, we create a single region for each cell.. This is inefficient, 1303 * but the implementation is quicker.. Probably later we will have to 1304 * consolidate styles into style regions. 1305 */ 1306 1307 style_region.setAttribute("startCol", QString::number(currentcolumn - 1)); 1308 style_region.setAttribute("startRow", QString::number(currentrow - 1)); 1309 style_region.setAttribute("endCol", QString::number(currentcolumn - 1)); 1310 style_region.setAttribute("endRow", QString::number(currentrow - 1)); 1311 1312 cell_style = GetCellStyle(gnumeric_doc, cell, currentcolumn, currentrow); 1313 1314 style_region.appendChild(cell_style); 1315 1316 styles.appendChild(style_region); 1317 1318 //cell_contents = gnumeric_doc.createElement("gmr:Content"); 1319 gnumeric_cell.appendChild(gnumeric_doc.createTextNode(text)); 1320 //gnumeric_cell.appendChild(cell_contents); 1321 } 1322 1323 // Append a delimiter, but in a temp string -> if no other real cell in this line, 1324 // then those will be dropped 1325 } 1326 } 1327 1328 if (mergedCells) 1329 sheet.appendChild(merged); 1330 } 1331 QDomElement uidata = gnumeric_doc.createElement("gmr:UIData"); 1332 uidata.setAttribute("SelectedTab", QString::number(indexActiveTable)); 1333 workbook.appendChild(uidata); 1334 1335 str = gnumeric_doc.toString(); 1336 1337 emit sigProgress(100); 1338 1339 // Ok, now write to export file 1340 1341 QIODevice* out = new KCompressionDevice(m_chain->outputFile(), KCompressionDevice::GZip); 1342 1343 if (!out) { 1344 qWarning() << "No output file! Aborting!"; 1345 return KoFilter::FileNotFound; 1346 } 1347 1348 if (!out->open(QIODevice::WriteOnly)) { 1349 qWarning() << "Unable to open output file! Aborting!"; 1350 delete out; 1351 return KoFilter::FileNotFound; 1352 } 1353 1354 QTextStream streamOut(out); 1355 1356 streamOut << str; 1357 streamOut.flush(); 1358 1359 out->close(); 1360 delete out; 1361 1362 return KoFilter::OK; 1363 } 1364 1365 1366 QString GNUMERICExport::convertRefToRange(const QString & table, const QRect & rect) 1367 { 1368 QPoint topLeft(rect.topLeft()); 1369 QPoint bottomRight(rect.bottomRight()); 1370 if (topLeft == bottomRight) 1371 return convertRefToBase(table, rect); 1372 QString s; 1373 s += table; 1374 s += "!$"; 1375 s += Cell::columnName(topLeft.x()); 1376 s += '$'; 1377 s += QString::number(topLeft.y()); 1378 s += ":$"; 1379 s += Cell::columnName(bottomRight.x()); 1380 s += '$'; 1381 s += QString::number(bottomRight.y()); 1382 1383 return s; 1384 } 1385 1386 1387 QString GNUMERICExport::convertRefToBase(const QString & table, const QRect & rect) 1388 { 1389 QPoint bottomRight(rect.bottomRight()); 1390 1391 QString s; 1392 s = table; 1393 s += "!$"; 1394 s += Cell::columnName(bottomRight.x()); 1395 s += '$'; 1396 s += QString::number(bottomRight.y()); 1397 1398 return s; 1399 } 1400 1401 QString GNUMERICExport::convertVariable(QString headerFooter) 1402 { 1403 headerFooter.replace("<sheet>", "&[TAB]"); 1404 headerFooter.replace("<date>", "&[DATE]"); 1405 headerFooter.replace("<page>", "&[PAGE]"); 1406 headerFooter.replace("<pages>", "&[PAGES]"); 1407 headerFooter.replace("<time>", "&[TIME]"); 1408 headerFooter.replace("<file>", "&[FILE]"); 1409 1410 return headerFooter; 1411 } 1412 1413 #include "gnumericexport.moc"