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