/* This file is part of the KDE project Copyright (C) 2000 David Faure Copyright (C) 2005 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* Gnumeric export filter by Phillip Ezolt (phillipezolt@hotmail.com) 2004 - Some updates by Tim Beaulen (tbscope@gmail.com) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KSpread; typedef KGenericFactory GNUMERICExportFactory; K_EXPORT_COMPONENT_FACTORY( libgnumericexport, GNUMERICExportFactory( "kofficefilters" ) ) GNUMERICExport::GNUMERICExport(KoFilter *, const char *, const TQStringList&) : KoFilter() { isLink = false; isLinkBold = false; isLinkItalic = false; } /** * This function will check if a cell has any type of border. */ bool GNUMERICExport::hasBorder(Cell *cell, int currentcolumn, int currentrow) { if ( ( (cell->format()->leftBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->leftBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) || ( (cell->format()->rightBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->rightBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) || ( (cell->format()->topBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->topBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) || ( (cell->format()->bottomBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->bottomBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) || ( (cell->format()->fallDiagonalWidth(currentcolumn, currentrow) != 0) && (cell->format()->fallDiagonalStyle(currentcolumn, currentrow) != TQt::NoPen ) ) || ( (cell->format()->goUpDiagonalWidth(currentcolumn, currentrow) != 0) && (cell->format()->goUpDiagonalStyle(currentcolumn, currentrow) != TQt::NoPen ) ) ) return true; else return false; } const TQString GNUMERICExport::ColorToString(int red, int green, int blue) { return TQString::number(red,16)+":"+TQString::number(green,16)+":"+TQString::number(blue,16); } TQDomElement GNUMERICExport::GetBorderStyle(TQDomDocument gnumeric_doc,Cell * cell, int currentcolumn, int currentrow) { TQDomElement border_style; TQDomElement border; int red, green, blue; TQColor color; border_style = gnumeric_doc.createElement("gmr:StyleBorder"); if ( (cell->format()->leftBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->leftBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) { border = gnumeric_doc.createElement("gmr:Left"); border.setAttribute("Style","1"); color = cell->format()->leftBorderColor(currentcolumn, currentrow); red = color.red()<<8; green = color.green()<<8; blue = color.blue()<<8; border.setAttribute("Color", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); } else { border = gnumeric_doc.createElement("gmr:Left"); border.setAttribute("Style","0"); } border_style.appendChild(border); if ( (cell->format()->rightBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->rightBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) { border = gnumeric_doc.createElement("gmr:Right"); border.setAttribute("Style","1"); color = cell->format()->rightBorderColor(currentcolumn, currentrow); red = color.red()<<8; green = color.green()<<8; blue = color.blue()<<8; border.setAttribute("Color", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); } else { border = gnumeric_doc.createElement("gmr:Right"); border.setAttribute("Style","0"); } border_style.appendChild(border); if ( (cell->format()->topBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->topBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) { border = gnumeric_doc.createElement("gmr:Top"); border.setAttribute("Style","1"); color = cell->format()->topBorderColor(currentcolumn, currentrow); red = color.red()<<8; green = color.green()<<8; blue = color.blue()<<8; border.setAttribute("Color", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); } else { border = gnumeric_doc.createElement("gmr:Top"); border.setAttribute("Style","0"); } border_style.appendChild(border); if ( (cell->format()->bottomBorderWidth(currentcolumn, currentrow) != 0) && (cell->format()->bottomBorderStyle(currentcolumn, currentrow) != TQt::NoPen ) ) { border = gnumeric_doc.createElement("gmr:Bottom"); border.setAttribute("Style","1"); color = cell->format()->bottomBorderColor(currentcolumn, currentrow); red = color.red()<<8; green = color.green()<<8; blue = color.blue()<<8; border.setAttribute("Color", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); } else { border = gnumeric_doc.createElement("gmr:Bottom"); border.setAttribute("Style","0"); } border_style.appendChild(border); if ( (cell->format()->fallDiagonalWidth(currentcolumn, currentrow) != 0) && (cell->format()->fallDiagonalStyle(currentcolumn, currentrow) != TQt::NoPen ) ) { border = gnumeric_doc.createElement("gmr:Diagonal"); border.setAttribute("Style","1"); color = cell->format()->fallDiagonalColor(currentcolumn, currentrow); red = color.red()<<8; green = color.green()<<8; blue = color.blue()<<8; border.setAttribute("Color", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); } else { border = gnumeric_doc.createElement("gmr:Diagonal"); border.setAttribute("Style","0"); } border_style.appendChild(border); if ( (cell->format()->goUpDiagonalWidth(currentcolumn, currentrow) != 0) && (cell->format()->goUpDiagonalStyle(currentcolumn, currentrow) != TQt::NoPen ) ) { border = gnumeric_doc.createElement("gmr:Rev-Diagonal"); border.setAttribute("Style","1"); color = cell->format()->goUpDiagonalColor(currentcolumn, currentrow); red = color.red()<<8; green = color.green()<<8; blue = color.blue()<<8; border.setAttribute("Color", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); } else { border = gnumeric_doc.createElement("gmr:Rev-Diagonal"); border.setAttribute("Style","0"); } border_style.appendChild(border); return border_style; } TQDomElement GNUMERICExport::GetValidity( TQDomDocument gnumeric_doc, Cell * cell ) { // // 45 // Validity *kspread_validity = cell->getValidity(); TQDomElement val = gnumeric_doc.createElement( "gmr:Validation" ); val.setAttribute( "Title", kspread_validity->title ); val.setAttribute( "Message", kspread_validity->message ); val.setAttribute( "AllowBlank", kspread_validity->allowEmptyCell ? "true":"false" ); if ( !kspread_validity->displayMessage ) { val.setAttribute("Style", "0" ); } else { switch( kspread_validity->m_action ) { case Action::Stop: val.setAttribute("Style", "1" ); break; case Action::Warning: val.setAttribute("Style", "2" ); break; case Action::Information: val.setAttribute("Style", "3" ); break; } } switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: val.setAttribute("Operator", "2" ); break; case Conditional::Superior: val.setAttribute("Operator", "4" ); break; case Conditional::Inferior: val.setAttribute("Operator", "5" ); break; case Conditional::SuperiorEqual: val.setAttribute("Operator", "6" ); break; case Conditional::InferiorEqual: val.setAttribute("Operator", "7" ); break; case Conditional::Between: val.setAttribute("Operator", "0" ); break; case Conditional::Different: val.setAttribute("Operator", "3" ); break; case Conditional::DifferentTo: val.setAttribute("Operator", "1" ); break; } switch( kspread_validity->m_restriction ) { case Restriction::None: val.setAttribute("Type", "0" ); break; case Restriction::Number: { val.setAttribute("Type", "2" ); switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: case Conditional::Superior: case Conditional::Inferior: case Conditional::SuperiorEqual: case Conditional::InferiorEqual: case Conditional::Different: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number( kspread_validity->valMin ) ) ); val.appendChild( tmp ); } break; case Conditional::Between: case Conditional::DifferentTo: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMin ) ) ); val.appendChild( tmp ); tmp = gnumeric_doc.createElement( "gmr:Expression1" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMax ) ) ); val.appendChild( tmp ); } break; } break; } case Restriction::Text: //Not supported into gnumeric //val.setAttribute("Type", "1" ); break; case Restriction::Time: val.setAttribute("Type", "5" ); switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: case Conditional::Superior: case Conditional::Inferior: case Conditional::SuperiorEqual: case Conditional::InferiorEqual: case Conditional::Different: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->timeMin.toString() ) ); val.appendChild( tmp ); } break; case Conditional::Between: case Conditional::DifferentTo: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->timeMin.toString() ) ); val.appendChild( tmp ); tmp = gnumeric_doc.createElement( "gmr:Expression1" ); tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->timeMax.toString() ) ); val.appendChild( tmp ); } break; } break; case Restriction::Date: val.setAttribute("Type", "4" ); switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: case Conditional::Superior: case Conditional::Inferior: case Conditional::SuperiorEqual: case Conditional::InferiorEqual: case Conditional::Different: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->dateMin.toString() ) ); val.appendChild( tmp ); } break; case Conditional::Between: case Conditional::DifferentTo: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->dateMin.toString() ) ); val.appendChild( tmp ); tmp = gnumeric_doc.createElement( "gmr:Expression1" ); tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->dateMax.toString() ) ); val.appendChild( tmp ); } break; } break; case Restriction::Integer: val.setAttribute("Type", "1" ); switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: case Conditional::Superior: case Conditional::Inferior: case Conditional::SuperiorEqual: case Conditional::InferiorEqual: case Conditional::Different: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMin ) ) ); val.appendChild( tmp ); } break; case Conditional::Between: case Conditional::DifferentTo: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMin ) ) ); val.appendChild( tmp ); tmp = gnumeric_doc.createElement( "gmr:Expression1" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMax ) ) ); val.appendChild( tmp ); } break; } break; case Restriction::TextLength: val.setAttribute("Type", "6" ); switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: case Conditional::Superior: case Conditional::Inferior: case Conditional::SuperiorEqual: case Conditional::InferiorEqual: case Conditional::Different: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMin ) ) ); val.appendChild( tmp ); } break; case Conditional::Between: case Conditional::DifferentTo: { TQDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMin ) ) ); val.appendChild( tmp ); tmp = gnumeric_doc.createElement( "gmr:Expression1" ); tmp.appendChild( gnumeric_doc.createTextNode( TQString::number(kspread_validity->valMax ) ) ); val.appendChild( tmp ); } break; } break; case Restriction::List: val.setAttribute("Type", "3" ); switch( kspread_validity->m_cond ) { case Conditional::None: //Nothing break; case Conditional::Equal: case Conditional::Superior: case Conditional::Inferior: case Conditional::SuperiorEqual: case Conditional::InferiorEqual: case Conditional::Different: break; case Conditional::Between: case Conditional::DifferentTo: break; } break; } return val; } TQDomElement GNUMERICExport::GetFontStyle( TQDomDocument gnumeric_doc,Cell * cell, int currentcolumn, int currentrow) { TQDomElement font_style; kdDebug()<<" currentcolumn :"<format()->textFontFamily(currentcolumn, currentrow))); if (cell->format()->textFontItalic(currentcolumn,currentrow) || (isLink && isLinkItalic)) { font_style.setAttribute("Italic","1"); } if (cell->format()->textFontBold(currentcolumn,currentrow) || (isLink && isLinkBold)) { font_style.setAttribute("Bold","1"); } if (cell->format()->textFontUnderline(currentcolumn,currentrow)) { font_style.setAttribute("Underline","1"); } if (cell->format()->textFontStrike(currentcolumn,currentrow)) { font_style.setAttribute("StrikeThrough","1"); } if (cell->format()->textFontSize(currentcolumn,currentrow)) { font_style.setAttribute("Unit",TQString::number(cell->format()->textFontSize(currentcolumn,currentrow))); } return font_style; } TQDomElement GNUMERICExport::GetLinkStyle(TQDomDocument gnumeric_doc) { TQDomElement link_style; link_style = gnumeric_doc.createElement("gmr:HyperLink"); TQString path; path = linkUrl; if (path.section(":",0,0).lower() == "http") link_style.setAttribute("type","GnmHLinkURL"); else if (path.section(":",0,0).lower() == "mailto") link_style.setAttribute("type","GnmHLinkEMail"); else if (path.section(":",0,0).lower() == "file") link_style.setAttribute("type","GnmHLinkExternal"); else if (path.left(5).lower() == "sheet") link_style.setAttribute("type","GnmHLinkCurWB"); else link_style.setAttribute("type",""); link_style.setAttribute("target",path); // KSpread doesn't support link tips. link_style.setAttribute("tip",""); return link_style; } TQDomElement GNUMERICExport::GetCellStyle(TQDomDocument gnumeric_doc,Cell * cell, int currentcolumn, int currentrow) { TQColorGroup defaultColorGroup = TQApplication::palette().active(); TQDomElement cell_style; cell_style = gnumeric_doc.createElement("gmr:Style"); int red, green, blue; TQColor bgColor = cell->bgColor(currentcolumn, currentrow); red = bgColor.red()<<8; green = bgColor.green()<<8; blue = bgColor.blue()<<8; switch (cell->format()->backGroundBrushStyle(currentcolumn, currentrow)) { case TQt::NoBrush: cell_style.setAttribute("Shade","0"); break; case TQt::SolidPattern: // 100% cell_style.setAttribute("Shade","1"); break; case TQt::Dense1Pattern: // 87.5% cell_style.setAttribute("Shade","25"); break; case TQt::Dense2Pattern: // 75% cell_style.setAttribute("Shade","2"); break; case TQt::Dense3Pattern: // 62.5% // Not supported by GNumeric // Fall back to 50% cell_style.setAttribute("Shade","3"); break; case TQt::Dense4Pattern: // 50% cell_style.setAttribute("Shade","3"); break; case TQt::Dense5Pattern: // 25% cell_style.setAttribute("Shade","4"); break; case TQt::Dense6Pattern: // 12.5% cell_style.setAttribute("Shade","5"); break; case TQt::Dense7Pattern: // 6.25% cell_style.setAttribute("Shade","6"); break; case TQt::HorPattern: cell_style.setAttribute("Shade","13"); break; case TQt::VerPattern: cell_style.setAttribute("Shade","14"); break; case TQt::CrossPattern: cell_style.setAttribute("Shade","17"); break; case TQt::BDiagPattern: cell_style.setAttribute("Shade","16"); break; case TQt::FDiagPattern: cell_style.setAttribute("Shade","15"); break; case TQt::DiagCrossPattern: cell_style.setAttribute("Shade","18"); break; case TQt::CustomPattern: // Not supported by Gnumeric cell_style.setAttribute("Shade","0"); break; } cell_style.setAttribute("Back",TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16) ); TQColor textColor = cell->format()->textColor(currentcolumn, currentrow); red = textColor.red()<<8; green = textColor.green()<<8; blue = textColor.blue()<<8; cell_style.setAttribute("Fore",TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16) ); if (cell->format()->align(currentcolumn,currentrow) == Format::Undefined) { cell_style.setAttribute("HAlign","1"); } else if (cell->format()->align(currentcolumn,currentrow) == Format::Left) { cell_style.setAttribute("HAlign","2"); } else if (cell->format()->align(currentcolumn,currentrow) == Format::Right) { cell_style.setAttribute("HAlign","4"); } else if (cell->format()->align(currentcolumn,currentrow) == Format::Center) { cell_style.setAttribute("HAlign","8"); } if (cell->format()->alignY(currentcolumn,currentrow) == Format::Top) { cell_style.setAttribute("VAlign","1"); } else if (cell->format()->alignY(currentcolumn,currentrow) == Format::Bottom) { cell_style.setAttribute("VAlign","2"); } else if (cell->format()->alignY(currentcolumn,currentrow) == Format::Middle) { cell_style.setAttribute("VAlign","4"); } if (cell->format()->multiRow(currentcolumn,currentrow)) cell_style.setAttribute("WrapText","1"); else cell_style.setAttribute("WrapText","0"); // ShrinkToFit not supported by KSpread (?) cell_style.setAttribute("ShrinkToFit","0"); // I'm not sure about the rotation values. // I never got it to work in GNumeric. cell_style.setAttribute("Rotation", TQString::number(-1*cell->format()->getAngle(currentcolumn,currentrow))); // The indentation in GNumeric is an integer value. In KSpread, it's a double. // Save the double anyway, makes it even better when importing the document back in KSpread. // TODO verify if it's correct, in import we "* 10.0" cell_style.setAttribute("Indent", TQString::number(cell->format()->getIndent(currentcolumn,currentrow))); cell_style.setAttribute("Locked", !cell->format()->notProtected(currentcolumn,currentrow)); // A KSpread cell can have two options to hide: only formula hidden, or everything hidden. // I only consider a cell with everything hidden as hidden. // Gnumeric hides everything or nothing. cell_style.setAttribute("Hidden", cell->format()->isHideAll(currentcolumn,currentrow)); TQColor patColor = cell->format()->backGroundBrushColor(currentcolumn, currentrow); red = patColor.red()<<8; green = patColor.green()<<8; blue = patColor.blue()<<8; cell_style.setAttribute("PatternColor", TQString::number(red,16)+":"+TQString::number(green,16) +":"+TQString::number(blue,16)); if (isLink) cell_style.appendChild(GetLinkStyle(gnumeric_doc)); cell_style.appendChild(GetFontStyle(gnumeric_doc, cell, currentcolumn, currentrow)); if ( cell->getValidity() ) { cell_style.appendChild( GetValidity( gnumeric_doc, cell ) ); } TQString stringFormat; Format::Currency c; Currency currency; switch( cell->format()->getFormatType(currentcolumn, currentrow)) { case Number_format: stringFormat="0.00"; break; case Text_format: stringFormat="general"; break; case Money_format: if (!cell->format()->currencyInfo(c)) { stringFormat = "0.00"; break; } if (currency.getCurrencyCode(c.type).isEmpty()) stringFormat = "0.00"; else if (currency.getCurrencyCode(c.type) == "$") stringFormat = "$0.00"; else if (currency.getCurrencyCode(c.type) == TQString::fromUtf8("€")) stringFormat = "[$€-2]0.00"; else if (currency.getCurrencyCode(c.type) == TQString::fromUtf8("£")) stringFormat = "£0.00"; else if (currency.getCurrencyCode(c.type) == TQString::fromUtf8("¥")) stringFormat = "¥0.00"; else stringFormat="[$" + currency.getCurrencyCode(c.type) + "]0.00"; break; case Percentage_format: stringFormat="0.00%"; break; case Scientific_format: stringFormat="0.00E+00"; break; case ShortDate_format: stringFormat=cell->locale()->dateFormatShort(); break; case TextDate_format: stringFormat=cell->locale()->dateFormat(); break; case date_format1: stringFormat="dd-mmm-yy"; break; case date_format2: stringFormat="dd-mmm-yyyy"; break; case date_format3: stringFormat="dd-mmm"; break; case date_format4: stringFormat="dd-mm"; break; case date_format5: stringFormat="dd/mm/yy"; break; case date_format6: stringFormat="dd/mm/yyyy"; break; case date_format7: stringFormat="mmm-yy"; break; case date_format8: stringFormat="mmmm-yy"; break; case date_format9: stringFormat="mmmm-yyyy"; break; case date_format10: stringFormat="m-yy"; break; case date_format11: stringFormat="dd/mmm"; break; case date_format12: stringFormat="dd/mm"; break; case date_format13: stringFormat="dd/mmm/yyyy"; break; case date_format14: stringFormat="yyyy/mmm/dd"; break; case date_format15: stringFormat="yyyy-mmm-dd"; break; case date_format16: stringFormat="yyyy-mm-dd"; break; case date_format17: stringFormat="d mmmm yyyy"; break; case date_format18: stringFormat="mm/dd/yyyy"; break; case date_format19: stringFormat="mm/dd/yy"; break; case date_format20: stringFormat="mmm/dd/yy"; break; case date_format21: stringFormat="mmm/dd/yyyy"; break; case date_format22: stringFormat="mmm-yyyy"; break; case date_format23: stringFormat="yyyy"; break; case date_format24: stringFormat="yy"; break; case date_format25: stringFormat="yyyy/mm/dd"; break; case date_format26: stringFormat="yyyy/mmm/dd"; break; case Time_format: case SecondeTime_format: stringFormat=cell->locale()->timeFormat(); break; case Time_format1: stringFormat = "h:mm AM/PM"; break; case Time_format2: stringFormat = "h:mm:ss AM/PM"; break; case Time_format3: stringFormat = "h \"h\" mm \"min\" ss \"s\""; break; case Time_format4: stringFormat = "h:mm"; break; case Time_format5: stringFormat = "h:mm:ss"; break; case Time_format6: stringFormat = "mm:ss"; break; case Time_format7: stringFormat = "[h]:mm:ss"; break; case Time_format8: stringFormat = "[h]:mm"; break; case fraction_half: stringFormat="# ?/2"; break; case fraction_quarter: stringFormat="# ?/4"; break; case fraction_eighth: stringFormat="# ?/8"; break; case fraction_sixteenth: stringFormat="# ?/16"; break; case fraction_tenth: stringFormat="# ?/10"; break; case fraction_hundredth: stringFormat="# ?/100"; break; case fraction_one_digit: stringFormat="# ?/?"; break; case fraction_two_digits: stringFormat="# ?\?/?\?"; break; case fraction_three_digits: stringFormat="# ?\?\?/?\?\?"; break; case Custom_format: stringFormat = cell->format()->getFormatString(currentcolumn,currentrow); break; default: break; } cell_style.setAttribute("Format",stringFormat); if(hasBorder(cell, currentcolumn, currentrow)) cell_style.appendChild(GetBorderStyle(gnumeric_doc, cell, currentcolumn, currentrow)); return cell_style; } void GNUMERICExport::addAttributeItem(TQDomDocument gnumeric_doc, TQDomElement attributes, const TQString& type, const TQString& name, bool value) { TQDomElement gmr_attribute, gmr_type, gmr_name, gmr_value; gmr_attribute = gnumeric_doc.createElement("gmr:Attribute"); attributes.appendChild(gmr_attribute); gmr_type = gnumeric_doc.createElement("gmr:type"); gmr_type.appendChild(gnumeric_doc.createTextNode(type)); gmr_attribute.appendChild(gmr_type); gmr_name = gnumeric_doc.createElement("gmr:name"); gmr_name.appendChild(gnumeric_doc.createTextNode(name)); gmr_attribute.appendChild(gmr_name); TQString txtValue; if (value) txtValue = "true"; else txtValue = "false"; gmr_value = gnumeric_doc.createElement("gmr:value"); gmr_value.appendChild(gnumeric_doc.createTextNode(txtValue)); gmr_attribute.appendChild(gmr_value); } void GNUMERICExport::addSummaryItem(TQDomDocument gnumeric_doc, TQDomElement summary, const TQString& name, const TQString& value) { if ( value.isEmpty() ) return; TQDomElement gmr_item, gmr_name, gmr_val_string; gmr_item = gnumeric_doc.createElement("gmr:Item"); summary.appendChild(gmr_item); gmr_name = gnumeric_doc.createElement("gmr:name"); gmr_name.appendChild(gnumeric_doc.createTextNode(name)); gmr_item.appendChild(gmr_name); gmr_val_string = gnumeric_doc.createElement("gmr:val-string"); gmr_val_string.appendChild(gnumeric_doc.createTextNode(value)); gmr_item.appendChild(gmr_val_string); } // The reason why we use the KoDocument* approach and not the TQDomDocument // approach is because we don't want to export formulas but values ! KoFilter::ConversionStatus GNUMERICExport::convert( const TQCString& from, const TQCString& to ) { kdDebug(30521) << "Exporting GNUmeric" << endl; TQDomDocument gnumeric_doc=TQDomDocument(); Sheet* table; KoDocument* document = m_chain->inputDocument(); if (!document) return KoFilter::StupidError; if ( !::tqqt_cast( document ) ) // it's safer that way :) { kdWarning(30521) << "document isn't a KSpread::Doc but a " << document->className() << endl; return KoFilter::NotImplemented; } if (to != "application/x-gnumeric" || from != "application/x-kspread") { kdWarning(30521) << "Invalid mimetypes " << to << " " << from << endl; return KoFilter::NotImplemented; } Doc* ksdoc = (Doc*)document; if (ksdoc->mimeType() != "application/x-kspread") { kdWarning(30521) << "Invalid document mimetype " << ksdoc->mimeType() << endl; return KoFilter::NotImplemented; } /* This could be Made into a function */ gnumeric_doc.appendChild( gnumeric_doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); TQDomElement workbook = gnumeric_doc.createElement("gmr:Workbook"); workbook.setAttribute("xmlns:gmr","http://www.gnumeric.org/v10.dtd"); workbook.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); workbook.setAttribute("xmlns:schemaLocation", "http://www.gnumeric.org/v8.xsd"); gnumeric_doc.appendChild(workbook); /* End Made into a function */ TQDomElement sheets,sheet,tmp,cells,selections, cols,rows,styles,merged, margins, top, left, bottom, right, orientation, paper, header, footer, customSize, cellComment, objects, repeatColumns, repeatRows; KoDocumentInfo *DocumentInfo = document->documentInfo(); KoDocumentInfoAbout *aboutPage = static_cast(DocumentInfo->page( "about" )); KoDocumentInfoAuthor *authorPage = static_cast(DocumentInfo->page( "author" )); /* * Attributes */ TQDomElement attributes = gnumeric_doc.createElement("gmr:Attributes"); workbook.appendChild(attributes); addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_horizontal_scrollbar", ksdoc->showHorizontalScrollBar()); addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_vertical_scrollbar", ksdoc->showVerticalScrollBar()); addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_notebook_tabs", ksdoc->showTabBar()); if (ksdoc->completionMode() == TDEGlobalSettings::CompletionAuto) addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::do_auto_completion", "true"); else addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::do_auto_completion", "false"); addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::is_protected", ksdoc->map()->isProtected()); /* * Doccument summary */ TQDomElement summary = gnumeric_doc.createElement("gmr:Summary"); workbook.appendChild(summary); addSummaryItem(gnumeric_doc, summary, "title", aboutPage->title()); addSummaryItem(gnumeric_doc, summary, "company", authorPage->company()); addSummaryItem(gnumeric_doc, summary, "author", authorPage->fullName()); addSummaryItem(gnumeric_doc, summary, "comments", aboutPage->abstract()); addSummaryItem(gnumeric_doc, summary, "keywords", aboutPage->keywords()); addSummaryItem(gnumeric_doc, summary, "application", "KSpread"); /* * Sheet name index (necessary for the gnumeric xml_sax importer) */ TQDomElement sheetNameIndex = gnumeric_doc.createElement("gmr:SheetNameIndex"); workbook.appendChild(sheetNameIndex); for (table = ksdoc->map()->firstSheet(); table != 0L; table =ksdoc->map()->nextSheet()) { TQDomElement sheetName = gnumeric_doc.createElement("gmr:SheetName"); sheetName.appendChild(gnumeric_doc.createTextNode(table->tableName())); sheetNameIndex.appendChild(sheetName); } /* * Area Names */ /* test Sheet2!$A$2:$D$10 A1 voiture Sheet2!$A$2:$D$8 A1 */ if ( ksdoc->listArea().count()>0 ) { TQDomElement areaNames = gnumeric_doc.createElement("gmr:Names"); const TQValueList &area = ksdoc->listArea(); // copying by value is slow! TQValueList::ConstIterator it = area.begin(); TQValueList::ConstIterator end = area.end(); for ( ; it != end; ++it ) { TQDomElement areaName = gnumeric_doc.createElement("gmr:Name"); TQDomElement areaNameElement = gnumeric_doc.createElement("gmr:name"); areaNameElement.appendChild(gnumeric_doc.createTextNode(( *it ).ref_name) ); areaName.appendChild( areaNameElement ); TQDomElement areaNameValue = gnumeric_doc.createElement("gmr:value"); areaNameValue.appendChild(gnumeric_doc.createTextNode( convertRefToRange( ( *it ).sheet_name, ( *it ).rect ) ) ); areaName.appendChild( areaNameValue ); areaNames.appendChild( areaName ); //TODO A1 I don't know what is it. } workbook.appendChild(areaNames); } /* * Sheets */ sheets = gnumeric_doc.createElement("gmr:Sheets"); workbook.appendChild(sheets); TQString str; View * view = static_cast( ksdoc->views().getFirst()); Canvas * canvas=0L; TQString activeTableName; if (view) { canvas = view->canvasWidget(); activeTableName = canvas->activeSheet()->sheetName(); } int i = 0; int indexActiveTable=0; for (table = ksdoc->map()->firstSheet(); table != 0L; table =ksdoc->map()->nextSheet(), i++) { if ( table->print()->paperFormat()==PG_CUSTOM ) { customSize = gnumeric_doc.createElement( "gmr:Geometry" ); customSize.setAttribute( "Width", POINT_TO_MM ( table->print()->paperWidth() )); customSize.setAttribute( "Height", POINT_TO_MM (table->print()->paperWidth() )); sheets.appendChild(customSize); // } sheet = gnumeric_doc.createElement("gmr:Sheet"); sheets.appendChild(sheet); sheet.setAttribute("DisplayFormulas", table->getShowFormula() ? "true" : "false" ); sheet.setAttribute("HideZero", table->getHideZero()? "true" : "false"); sheet.setAttribute("HideGrid", !table->getShowGrid()? "true" : "false"); sheet.setAttribute("HideColHeader", ( !ksdoc->showColumnHeader() ? "true" : "false" )); sheet.setAttribute("HideRowHeader", ( !ksdoc->showRowHeader()? "true" : "false" )); /* Not available in KSpread ? * sheet.setAttribute("DisplayOutlines", "true"); * sheet.setAttribute("OutlineSymbolsBelow", "true"); * sheet.setAttribute("OutlineSymbolsRight", "true"); * sheet.setAttribute("TabColor", ""); * sheet.setAttribute("TabTextColor", ""); */ tmp = gnumeric_doc.createElement("gmr:Name"); if ( table->tableName()==activeTableName ) indexActiveTable = i; tmp.appendChild(gnumeric_doc.createTextNode(table->tableName())); sheet.appendChild(tmp); tmp = gnumeric_doc.createElement("gmr:MaxCol"); tmp.appendChild(gnumeric_doc.createTextNode(TQString::number(table->maxColumn()))); sheet.appendChild(tmp); tmp = gnumeric_doc.createElement("gmr:MaxRow"); tmp.appendChild(gnumeric_doc.createTextNode(TQString::number(table->maxRow()))); sheet.appendChild(tmp); // Zoom value doesn't appear to be correct // KSpread 200% gives zoom() = 2.5, this in GNumeric = 250% tmp = gnumeric_doc.createElement("gmr:Zoom"); if (view) tmp.appendChild(gnumeric_doc.createTextNode(TQString::number(canvas->zoom()))); else tmp.appendChild(gnumeric_doc.createTextNode("1.0")); sheet.appendChild(tmp); //Print Info tmp = gnumeric_doc.createElement( "gmr:PrintInformation" ); margins = gnumeric_doc.createElement( "gmr:Margins" ); top = gnumeric_doc.createElement( "gmr:top" ); top.setAttribute("Points", table->print()->topBorder()); top.setAttribute("PrefUnit", "mm"); margins.appendChild( top ); bottom = gnumeric_doc.createElement( "gmr:bottom" ); bottom.setAttribute("Points", table->print()->bottomBorder()); bottom.setAttribute("PrefUnit", "mm"); margins.appendChild( bottom ); left = gnumeric_doc.createElement( "gmr:left" ); left.setAttribute("Points", table->print()->leftBorder()); left.setAttribute("PrefUnit", "mm"); margins.appendChild( left ); right = gnumeric_doc.createElement( "gmr:right" ); right.setAttribute("Points", table->print()->rightBorder()); right.setAttribute("PrefUnit", "mm"); margins.appendChild( right ); tmp.appendChild( margins ); sheet.appendChild(tmp); orientation = gnumeric_doc.createElement( "gmr:orientation" ); TQString orientString = table->print()->orientation() == PG_LANDSCAPE ? "landscape" : "portrait"; orientation.appendChild( gnumeric_doc.createTextNode(orientString) ); tmp.appendChild( orientation ); //TODO for future // // int _tmpRepeatColumnStart = table->print()->printRepeatColumns().first; int _tmpRepeatColumnEnd = table->print()->printRepeatColumns().second; if ( _tmpRepeatColumnStart!=0 ) { repeatColumns = gnumeric_doc.createElement( "gmr:repeat_left" ); TQString value = Cell::columnName( _tmpRepeatColumnStart )+"1:"+Cell::columnName(_tmpRepeatColumnEnd )+"65536"; repeatColumns.setAttribute( "value", value ); tmp.appendChild( repeatColumns ); } int _tmpRepeatRowStart = table->print()->printRepeatRows().first; int _tmpRepeatRowEnd = table->print()->printRepeatRows().second; if ( _tmpRepeatRowStart!=0 ) { repeatRows = gnumeric_doc.createElement( "gmr:repeat_top" ); TQString value = "A"+ TQString::number(_tmpRepeatRowStart ) +":IV"+TQString::number( _tmpRepeatRowEnd ); repeatRows.setAttribute( "value", value ); tmp.appendChild( repeatRows ); } header = gnumeric_doc.createElement( "gmr:Header" ); header.setAttribute( "Left", convertVariable(table->print()->headLeft() ) ); header.setAttribute( "Middle", convertVariable(table->print()->headMid() ) ); header.setAttribute( "Right", convertVariable(table->print()->headRight() ) ); tmp.appendChild( header ); footer = gnumeric_doc.createElement( "gmr:Footer" ); footer.setAttribute( "Left", convertVariable( table->print()->footLeft() ) ); footer.setAttribute( "Middle", convertVariable( table->print()->footMid() ) ); footer.setAttribute( "Right", convertVariable( table->print()->footRight() )); tmp.appendChild( footer ); paper = gnumeric_doc.createElement( "gmr:paper" ); paper.appendChild( gnumeric_doc.createTextNode( table->print()->paperFormatString() ) ); tmp.appendChild( paper ); styles = gnumeric_doc.createElement("gmr:Styles"); sheet.appendChild(styles); cells = gnumeric_doc.createElement("gmr:Cells"); sheet.appendChild(cells); objects = gnumeric_doc.createElement("gmr:Objects"); sheet.appendChild(objects); merged = gnumeric_doc.createElement("gmr:MergedRegions"); bool mergedCells = false; // if there are no merged cells in this sheet, don't write an // empty mergedRegions to the file. // So, depending on the value of mergedCells, // the merged dom element is added or not. cols = gnumeric_doc.createElement("gmr:Cols"); sheet.appendChild(cols); rows = gnumeric_doc.createElement("gmr:Rows"); sheet.appendChild(rows); /* selections = gnumeric_doc.createElement("gmr:Selections"); sheet.appendChild(selections); */ // Ah ah ah - the document is const, but the map and table aren't. Safety: 0. // Either we get hold of Sheet::m_dctCells and apply the old method below // (for sorting) or, cleaner and already sorted, we use Sheet's API // (slower probably, though) int iMaxColumn = table->maxColumn(); int iMaxRow = table->maxRow(); // this is just a bad approximation which fails for documents with less than 50 rows, but // we don't need any progress stuff there anyway :) (Werner) int value=0; int step=iMaxRow > 50 ? iMaxRow/50 : 1; int i=1; TQString emptyLines; /* Save selection info. */ /* can't save selection anymore -- part of the view, not table */ /* TQDomElement selection = gnumeric_doc.createElement("gmr:Selection"); TQRect table_selection(table->selection()); selections.appendChild(selection); */ /* */ /* selection.setAttribute("startCol", TQString::number(table_selection.left()-1)); selection.setAttribute("startRow", TQString::number(table_selection.top()-1)); selection.setAttribute("endCol", TQString::number(table_selection.right()-1)); selection.setAttribute("endRow", TQString::number(table_selection.bottom()-1)); */ /* End selection info. */ /* Start COLS */ ColumnFormat *cl=table->firstCol(); while (cl) { TQDomElement colinfo = gnumeric_doc.createElement("gmr:ColInfo"); cols.appendChild(colinfo); colinfo.setAttribute("No", TQString::number(cl->column()-1)); colinfo.setAttribute("Hidden", TQString::number(cl->isHide())); colinfo.setAttribute("Unit", TQString::number(cl->dblWidth())); cl=cl->next(); } /* End COLS */ // RowFormat *rl=table->m_cells.firstCell; //