filters

gnumericexport.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2000 David Faure <faure@kde.org>
00003    Copyright (C) 2005 Laurent Montel <montel@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 /* Gnumeric export filter by Phillip Ezolt (phillipezolt@hotmail.com)
00022    2004 - Some updates by Tim Beaulen (tbscope@gmail.com) */
00023 
00024 #include <gnumericexport.h>
00025 #include <kdebug.h>
00026 #include <kfilterdev.h>
00027 #include <kmessagebox.h>
00028 #include <kgenericfactory.h>
00029 #include <KoFilterChain.h>
00030 #include <qapplication.h>
00031 #include <qptrlist.h>
00032 #include <qsortedlist.h>
00033 #include <qfile.h>
00034 #include <qtextstream.h>
00035 
00036 #include <kspread_map.h>
00037 #include <kspread_sheet.h>
00038 #include <kspread_doc.h>
00039 #include <kspread_view.h>
00040 #include <kspread_canvas.h>
00041 #include <kspread_sheetprint.h>
00042 #include <KoDocumentInfo.h>
00043 
00044 using namespace KSpread;
00045 
00046 typedef KGenericFactory<GNUMERICExport, KoFilter> GNUMERICExportFactory;
00047 K_EXPORT_COMPONENT_FACTORY( libgnumericexport, GNUMERICExportFactory( "kofficefilters" ) )
00048 
00049 GNUMERICExport::GNUMERICExport(KoFilter *, const char *, const QStringList&) :
00050 KoFilter()
00051 {
00052     isLink = false;
00053     isLinkBold = false;
00054     isLinkItalic = false;
00055 }
00056 
00060 bool GNUMERICExport::hasBorder(Cell *cell, int currentcolumn, int currentrow)
00061 {
00062     if ( ( (cell->format()->leftBorderWidth(currentcolumn, currentrow) != 0) &&
00063            (cell->format()->leftBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) ) ||
00064          ( (cell->format()->rightBorderWidth(currentcolumn, currentrow) != 0) &&
00065            (cell->format()->rightBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) ) ||
00066          ( (cell->format()->topBorderWidth(currentcolumn, currentrow) != 0) &&
00067            (cell->format()->topBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) ) ||
00068          ( (cell->format()->bottomBorderWidth(currentcolumn, currentrow) != 0) &&
00069            (cell->format()->bottomBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) ) ||
00070          ( (cell->format()->fallDiagonalWidth(currentcolumn, currentrow) != 0) &&
00071            (cell->format()->fallDiagonalStyle(currentcolumn, currentrow) != Qt::NoPen ) ) ||
00072          ( (cell->format()->goUpDiagonalWidth(currentcolumn, currentrow) != 0) &&
00073            (cell->format()->goUpDiagonalStyle(currentcolumn, currentrow) != Qt::NoPen ) ) )
00074         return true;
00075     else
00076         return false;
00077 }
00078 
00079 const QString GNUMERICExport::ColorToString(int red, int green, int blue)
00080 {
00081     return QString::number(red,16)+":"+QString::number(green,16)+":"+QString::number(blue,16);
00082 }
00083 
00084 QDomElement GNUMERICExport::GetBorderStyle(QDomDocument gnumeric_doc,Cell * cell, int currentcolumn, int currentrow)
00085 {
00086     QDomElement border_style;
00087     QDomElement border;
00088 
00089     int red, green, blue;
00090     QColor color;
00091 
00092     border_style = gnumeric_doc.createElement("gmr:StyleBorder");
00093 
00094     if ( (cell->format()->leftBorderWidth(currentcolumn, currentrow) != 0) &&
00095          (cell->format()->leftBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) )
00096     {
00097         border = gnumeric_doc.createElement("gmr:Left");
00098         border.setAttribute("Style","1");
00099 
00100         color =  cell->format()->leftBorderColor(currentcolumn, currentrow);
00101         red = color.red()<<8;
00102         green = color.green()<<8;
00103         blue = color.blue()<<8;
00104 
00105         border.setAttribute("Color", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00106     }
00107     else
00108     {
00109         border = gnumeric_doc.createElement("gmr:Left");
00110         border.setAttribute("Style","0");
00111     }
00112 
00113     border_style.appendChild(border);
00114 
00115     if ( (cell->format()->rightBorderWidth(currentcolumn, currentrow) != 0) &&
00116          (cell->format()->rightBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) )
00117     {
00118         border = gnumeric_doc.createElement("gmr:Right");
00119         border.setAttribute("Style","1");
00120 
00121         color =  cell->format()->rightBorderColor(currentcolumn, currentrow);
00122         red = color.red()<<8;
00123         green = color.green()<<8;
00124         blue = color.blue()<<8;
00125 
00126         border.setAttribute("Color", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00127     }
00128     else
00129     {
00130         border = gnumeric_doc.createElement("gmr:Right");
00131         border.setAttribute("Style","0");
00132     }
00133 
00134     border_style.appendChild(border);
00135 
00136     if ( (cell->format()->topBorderWidth(currentcolumn, currentrow) != 0) &&
00137          (cell->format()->topBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) )
00138     {
00139         border = gnumeric_doc.createElement("gmr:Top");
00140         border.setAttribute("Style","1");
00141 
00142         color =  cell->format()->topBorderColor(currentcolumn, currentrow);
00143         red = color.red()<<8;
00144         green = color.green()<<8;
00145         blue = color.blue()<<8;
00146 
00147         border.setAttribute("Color", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00148     }
00149     else
00150     {
00151         border = gnumeric_doc.createElement("gmr:Top");
00152         border.setAttribute("Style","0");
00153     }
00154 
00155     border_style.appendChild(border);
00156 
00157     if ( (cell->format()->bottomBorderWidth(currentcolumn, currentrow) != 0) &&
00158          (cell->format()->bottomBorderStyle(currentcolumn, currentrow) != Qt::NoPen ) )
00159     {
00160         border = gnumeric_doc.createElement("gmr:Bottom");
00161         border.setAttribute("Style","1");
00162 
00163         color =  cell->format()->bottomBorderColor(currentcolumn, currentrow);
00164         red = color.red()<<8;
00165         green = color.green()<<8;
00166         blue = color.blue()<<8;
00167 
00168         border.setAttribute("Color", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00169     }
00170     else
00171     {
00172         border = gnumeric_doc.createElement("gmr:Bottom");
00173         border.setAttribute("Style","0");
00174     }
00175 
00176     border_style.appendChild(border);
00177 
00178     if ( (cell->format()->fallDiagonalWidth(currentcolumn, currentrow) != 0) &&
00179          (cell->format()->fallDiagonalStyle(currentcolumn, currentrow) != Qt::NoPen ) )
00180     {
00181         border = gnumeric_doc.createElement("gmr:Diagonal");
00182         border.setAttribute("Style","1");
00183 
00184         color =  cell->format()->fallDiagonalColor(currentcolumn, currentrow);
00185         red = color.red()<<8;
00186         green = color.green()<<8;
00187         blue = color.blue()<<8;
00188 
00189         border.setAttribute("Color", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00190     }
00191     else
00192     {
00193         border = gnumeric_doc.createElement("gmr:Diagonal");
00194         border.setAttribute("Style","0");
00195     }
00196 
00197     border_style.appendChild(border);
00198 
00199     if ( (cell->format()->goUpDiagonalWidth(currentcolumn, currentrow) != 0) &&
00200          (cell->format()->goUpDiagonalStyle(currentcolumn, currentrow) != Qt::NoPen ) )
00201     {
00202         border = gnumeric_doc.createElement("gmr:Rev-Diagonal");
00203         border.setAttribute("Style","1");
00204 
00205         color =  cell->format()->goUpDiagonalColor(currentcolumn, currentrow);
00206         red = color.red()<<8;
00207         green = color.green()<<8;
00208         blue = color.blue()<<8;
00209 
00210         border.setAttribute("Color", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00211     }
00212     else
00213     {
00214         border = gnumeric_doc.createElement("gmr:Rev-Diagonal");
00215         border.setAttribute("Style","0");
00216     }
00217 
00218     border_style.appendChild(border);
00219 
00220     return border_style;
00221 }
00222 
00223 QDomElement GNUMERICExport::GetValidity( QDomDocument gnumeric_doc, Cell * cell )
00224 {
00225     //<gmr:Validation Style="1" Type="1" Operator="7" AllowBlank="true" UseDropdown="false" Title="ghhg" Message="ghghhhjfhfghjfghj&#10;fg&#10;hjgf&#10;hj">
00226     //        <gmr:Expression0>45</gmr:Expression0>
00227     //      </gmr:Validation>
00228     Validity *kspread_validity = cell->getValidity();
00229     QDomElement val = gnumeric_doc.createElement( "gmr:Validation" );
00230     val.setAttribute( "Title", kspread_validity->title );
00231     val.setAttribute( "Message", kspread_validity->message );
00232     val.setAttribute( "AllowBlank", kspread_validity->allowEmptyCell ? "true":"false" );
00233     if ( !kspread_validity->displayMessage )
00234     {
00235         val.setAttribute("Style", "0" );
00236     }
00237     else
00238     {
00239         switch( kspread_validity->m_action )
00240         {
00241           case Action::Stop:
00242             val.setAttribute("Style", "1" );
00243             break;
00244           case Action::Warning:
00245             val.setAttribute("Style", "2" );
00246             break;
00247           case Action::Information:
00248             val.setAttribute("Style", "3" );
00249             break;
00250         }
00251     }
00252 
00253     switch( kspread_validity->m_cond )
00254     {
00255       case Conditional::None:
00256         //Nothing
00257         break;
00258       case Conditional::Equal:
00259         val.setAttribute("Operator", "2" );
00260         break;
00261       case Conditional::Superior:
00262         val.setAttribute("Operator", "4" );
00263         break;
00264       case Conditional::Inferior:
00265         val.setAttribute("Operator", "5" );
00266         break;
00267       case Conditional::SuperiorEqual:
00268         val.setAttribute("Operator", "6" );
00269         break;
00270       case Conditional::InferiorEqual:
00271         val.setAttribute("Operator", "7" );
00272         break;
00273       case Conditional::Between:
00274         val.setAttribute("Operator", "0" );
00275         break;
00276       case Conditional::Different:
00277         val.setAttribute("Operator", "3" );
00278         break;
00279       case Conditional::DifferentTo:
00280         val.setAttribute("Operator", "1" );
00281         break;
00282     }
00283     switch( kspread_validity->m_restriction )
00284     {
00285     case Restriction::None:
00286         val.setAttribute("Type", "0" );
00287         break;
00288     case Restriction::Number:
00289     {
00290         val.setAttribute("Type", "2" );
00291         switch( kspread_validity->m_cond )
00292         {
00293           case Conditional::None:
00294             //Nothing
00295             break;
00296           case Conditional::Equal:
00297           case Conditional::Superior:
00298           case Conditional::Inferior:
00299           case Conditional::SuperiorEqual:
00300           case Conditional::InferiorEqual:
00301           case Conditional::Different:
00302         {
00303             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00304             tmp.appendChild( gnumeric_doc.createTextNode( QString::number( kspread_validity->valMin ) ) );
00305             val.appendChild( tmp );
00306         }
00307         break;
00308           case Conditional::Between:
00309           case Conditional::DifferentTo:
00310         {
00311             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00312             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMin ) ) );
00313             val.appendChild( tmp );
00314             tmp = gnumeric_doc.createElement( "gmr:Expression1" );
00315             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMax ) ) );
00316             val.appendChild( tmp );
00317         }
00318         break;
00319         }
00320 
00321         break;
00322     }
00323     case Restriction::Text:
00324         //Not supported into gnumeric
00325         //val.setAttribute("Type", "1" );
00326         break;
00327     case Restriction::Time:
00328         val.setAttribute("Type", "5" );
00329         switch( kspread_validity->m_cond )
00330         {
00331           case Conditional::None:
00332             //Nothing
00333             break;
00334           case Conditional::Equal:
00335           case Conditional::Superior:
00336           case Conditional::Inferior:
00337           case Conditional::SuperiorEqual:
00338           case Conditional::InferiorEqual:
00339           case Conditional::Different:
00340         {
00341             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00342             tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->timeMin.toString() ) );
00343             val.appendChild( tmp );
00344         }
00345         break;
00346           case Conditional::Between:
00347           case Conditional::DifferentTo:
00348         {
00349             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00350             tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->timeMin.toString() ) );
00351             val.appendChild( tmp );
00352             tmp = gnumeric_doc.createElement( "gmr:Expression1" );
00353             tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->timeMax.toString() ) );
00354             val.appendChild( tmp );
00355         }
00356         break;
00357         }
00358 
00359         break;
00360     case Restriction::Date:
00361         val.setAttribute("Type", "4" );
00362         switch( kspread_validity->m_cond )
00363         {
00364           case Conditional::None:
00365             //Nothing
00366             break;
00367           case Conditional::Equal:
00368           case Conditional::Superior:
00369           case Conditional::Inferior:
00370           case Conditional::SuperiorEqual:
00371           case Conditional::InferiorEqual:
00372           case Conditional::Different:
00373         {
00374             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00375             tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->dateMin.toString() ) );
00376             val.appendChild( tmp );
00377         }
00378         break;
00379           case Conditional::Between:
00380           case Conditional::DifferentTo:
00381         {
00382             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00383             tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->dateMin.toString() ) );
00384             val.appendChild( tmp );
00385             tmp = gnumeric_doc.createElement( "gmr:Expression1" );
00386             tmp.appendChild( gnumeric_doc.createTextNode( kspread_validity->dateMax.toString() ) );
00387             val.appendChild( tmp );
00388         }
00389         break;
00390         }
00391 
00392         break;
00393     case Restriction::Integer:
00394         val.setAttribute("Type", "1" );
00395         switch( kspread_validity->m_cond )
00396         {
00397           case Conditional::None:
00398             //Nothing
00399             break;
00400           case Conditional::Equal:
00401           case Conditional::Superior:
00402           case Conditional::Inferior:
00403           case Conditional::SuperiorEqual:
00404           case Conditional::InferiorEqual:
00405           case Conditional::Different:
00406         {
00407             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00408             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMin ) ) );
00409             val.appendChild( tmp );
00410         }
00411         break;
00412           case Conditional::Between:
00413           case Conditional::DifferentTo:
00414         {
00415             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00416             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMin ) ) );
00417             val.appendChild( tmp );
00418             tmp = gnumeric_doc.createElement( "gmr:Expression1" );
00419             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMax ) ) );
00420             val.appendChild( tmp );
00421         }
00422         break;
00423         }
00424         break;
00425     case Restriction::TextLength:
00426         val.setAttribute("Type", "6" );
00427         switch( kspread_validity->m_cond )
00428         {
00429           case Conditional::None:
00430             //Nothing
00431             break;
00432           case Conditional::Equal:
00433           case Conditional::Superior:
00434           case Conditional::Inferior:
00435           case Conditional::SuperiorEqual:
00436           case Conditional::InferiorEqual:
00437           case Conditional::Different:
00438         {
00439             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00440             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMin ) ) );
00441             val.appendChild( tmp );
00442         }
00443         break;
00444           case Conditional::Between:
00445           case Conditional::DifferentTo:
00446         {
00447             QDomElement tmp = gnumeric_doc.createElement( "gmr:Expression0" );
00448             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMin ) ) );
00449             val.appendChild( tmp );
00450             tmp = gnumeric_doc.createElement( "gmr:Expression1" );
00451             tmp.appendChild( gnumeric_doc.createTextNode( QString::number(kspread_validity->valMax ) ) );
00452             val.appendChild( tmp );
00453         }
00454         break;
00455         }
00456         break;
00457     case Restriction::List:
00458         val.setAttribute("Type", "3" );
00459         switch( kspread_validity->m_cond )
00460         {
00461           case Conditional::None:
00462             //Nothing
00463             break;
00464           case Conditional::Equal:
00465           case Conditional::Superior:
00466           case Conditional::Inferior:
00467           case Conditional::SuperiorEqual:
00468           case Conditional::InferiorEqual:
00469           case Conditional::Different:
00470             break;
00471           case Conditional::Between:
00472           case Conditional::DifferentTo:
00473             break;
00474         }
00475         break;
00476     }
00477 
00478     return val;
00479 }
00480 
00481 QDomElement GNUMERICExport::GetFontStyle( QDomDocument gnumeric_doc,Cell * cell, int currentcolumn, int currentrow)
00482 {
00483     QDomElement font_style;
00484     kdDebug()<<" currentcolumn :"<<currentcolumn<<" currentrow :"<<currentrow<<endl;
00485     font_style = gnumeric_doc.createElement("gmr:Font");
00486     font_style.appendChild(gnumeric_doc.createTextNode(cell->format()->textFontFamily(currentcolumn, currentrow)));
00487 
00488     if (cell->format()->textFontItalic(currentcolumn,currentrow) || (isLink && isLinkItalic))
00489     {
00490         font_style.setAttribute("Italic","1");
00491     }
00492     if (cell->format()->textFontBold(currentcolumn,currentrow) || (isLink && isLinkBold))
00493     {
00494         font_style.setAttribute("Bold","1");
00495     }
00496     if (cell->format()->textFontUnderline(currentcolumn,currentrow))
00497     {
00498         font_style.setAttribute("Underline","1");
00499     }
00500     if (cell->format()->textFontStrike(currentcolumn,currentrow))
00501     {
00502         font_style.setAttribute("StrikeThrough","1");
00503     }
00504     if (cell->format()->textFontSize(currentcolumn,currentrow))
00505     {
00506         font_style.setAttribute("Unit",QString::number(cell->format()->textFontSize(currentcolumn,currentrow)));
00507     }
00508 
00509     return font_style;
00510 }
00511 
00512 QDomElement GNUMERICExport::GetLinkStyle(QDomDocument gnumeric_doc)
00513 {
00514     QDomElement link_style;
00515 
00516     link_style = gnumeric_doc.createElement("gmr:HyperLink");
00517 
00518     QString path;
00519 
00520     path = linkUrl;
00521 
00522     if (path.section(":",0,0).lower() == "http")
00523         link_style.setAttribute("type","GnmHLinkURL");
00524     else if (path.section(":",0,0).lower() == "mailto")
00525         link_style.setAttribute("type","GnmHLinkEMail");
00526     else if (path.section(":",0,0).lower() == "file")
00527         link_style.setAttribute("type","GnmHLinkExternal");
00528     else if (path.left(5).lower() == "sheet")
00529         link_style.setAttribute("type","GnmHLinkCurWB");
00530     else
00531         link_style.setAttribute("type","");
00532 
00533     link_style.setAttribute("target",path);
00534 
00535     // KSpread doesn't support link tips.
00536     link_style.setAttribute("tip","");
00537 
00538     return link_style;
00539 }
00540 
00541 QDomElement GNUMERICExport::GetCellStyle(QDomDocument gnumeric_doc,Cell * cell, int currentcolumn, int currentrow)
00542 {
00543     QColorGroup defaultColorGroup = QApplication::palette().active();
00544 
00545     QDomElement cell_style;
00546 
00547     cell_style = gnumeric_doc.createElement("gmr:Style");
00548 
00549     int red, green, blue;
00550 
00551     QColor bgColor =  cell->bgColor(currentcolumn, currentrow);
00552     red = bgColor.red()<<8;
00553     green = bgColor.green()<<8;
00554     blue = bgColor.blue()<<8;
00555 
00556     switch (cell->format()->backGroundBrushStyle(currentcolumn, currentrow))
00557     {
00558         case Qt::NoBrush:
00559             cell_style.setAttribute("Shade","0");
00560             break;
00561         case Qt::SolidPattern:
00562             // 100%
00563             cell_style.setAttribute("Shade","1");
00564             break;
00565         case Qt::Dense1Pattern:
00566             // 87.5%
00567             cell_style.setAttribute("Shade","25");
00568             break;
00569         case Qt::Dense2Pattern:
00570             // 75%
00571             cell_style.setAttribute("Shade","2");
00572             break;
00573         case Qt::Dense3Pattern:
00574             // 62.5%
00575             // Not supported by GNumeric
00576             // Fall back to 50%
00577             cell_style.setAttribute("Shade","3");
00578             break;
00579         case Qt::Dense4Pattern:
00580             // 50%
00581             cell_style.setAttribute("Shade","3");
00582             break;
00583         case Qt::Dense5Pattern:
00584             // 25%
00585             cell_style.setAttribute("Shade","4");
00586             break;
00587         case Qt::Dense6Pattern:
00588             // 12.5%
00589             cell_style.setAttribute("Shade","5");
00590             break;
00591         case Qt::Dense7Pattern:
00592             // 6.25%
00593             cell_style.setAttribute("Shade","6");
00594             break;
00595         case Qt::HorPattern:
00596             cell_style.setAttribute("Shade","13");
00597             break;
00598         case Qt::VerPattern:
00599             cell_style.setAttribute("Shade","14");
00600             break;
00601         case Qt::CrossPattern:
00602             cell_style.setAttribute("Shade","17");
00603             break;
00604         case Qt::BDiagPattern:
00605             cell_style.setAttribute("Shade","16");
00606             break;
00607         case Qt::FDiagPattern:
00608             cell_style.setAttribute("Shade","15");
00609             break;
00610         case Qt::DiagCrossPattern:
00611             cell_style.setAttribute("Shade","18");
00612             break;
00613         case Qt::CustomPattern:
00614             // Not supported by Gnumeric
00615             cell_style.setAttribute("Shade","0");
00616             break;
00617     }
00618 
00619     cell_style.setAttribute("Back",QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16) );
00620 
00621 
00622     QColor textColor =  cell->format()->textColor(currentcolumn, currentrow);
00623     red = textColor.red()<<8;
00624     green = textColor.green()<<8;
00625     blue = textColor.blue()<<8;
00626 
00627     cell_style.setAttribute("Fore",QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16) );
00628 
00629  if (cell->format()->align(currentcolumn,currentrow) ==  Format::Undefined)
00630     {
00631         cell_style.setAttribute("HAlign","1");
00632     }
00633     else if (cell->format()->align(currentcolumn,currentrow) ==  Format::Left)
00634     {
00635         cell_style.setAttribute("HAlign","2");
00636     }
00637     else if (cell->format()->align(currentcolumn,currentrow) ==  Format::Right)
00638     {
00639         cell_style.setAttribute("HAlign","4");
00640     }
00641  else if (cell->format()->align(currentcolumn,currentrow) ==  Format::Center)
00642     {
00643         cell_style.setAttribute("HAlign","8");
00644     }
00645 
00646     if (cell->format()->alignY(currentcolumn,currentrow) ==  Format::Top)
00647     {
00648         cell_style.setAttribute("VAlign","1");
00649     }
00650  else if (cell->format()->alignY(currentcolumn,currentrow) ==  Format::Bottom)
00651     {
00652         cell_style.setAttribute("VAlign","2");
00653     }
00654     else if (cell->format()->alignY(currentcolumn,currentrow) ==  Format::Middle)
00655     {
00656         cell_style.setAttribute("VAlign","4");
00657     }
00658 
00659     if (cell->format()->multiRow(currentcolumn,currentrow))
00660         cell_style.setAttribute("WrapText","1");
00661     else
00662         cell_style.setAttribute("WrapText","0");
00663 
00664     // ShrinkToFit not supported by KSpread (?)
00665     cell_style.setAttribute("ShrinkToFit","0");
00666 
00667     // I'm not sure about the rotation values.
00668     // I never got it to work in GNumeric.
00669     cell_style.setAttribute("Rotation", QString::number(-1*cell->format()->getAngle(currentcolumn,currentrow)));
00670 
00671     // The indentation in GNumeric is an integer value. In KSpread, it's a double.
00672     // Save the double anyway, makes it even better when importing the document back in KSpread.
00673     // TODO verify if it's correct, in import we "* 10.0"
00674     cell_style.setAttribute("Indent", QString::number(cell->format()->getIndent(currentcolumn,currentrow)));
00675 
00676     cell_style.setAttribute("Locked", !cell->format()->notProtected(currentcolumn,currentrow));
00677 
00678     // A KSpread cell can have two options to hide: only formula hidden, or everything hidden.
00679     // I only consider a cell with everything hidden as hidden.
00680     // Gnumeric hides everything or nothing.
00681     cell_style.setAttribute("Hidden", cell->format()->isHideAll(currentcolumn,currentrow));
00682 
00683     QColor patColor =  cell->format()->backGroundBrushColor(currentcolumn, currentrow);
00684     red = patColor.red()<<8;
00685     green = patColor.green()<<8;
00686     blue = patColor.blue()<<8;
00687 
00688     cell_style.setAttribute("PatternColor", QString::number(red,16)+":"+QString::number(green,16) +":"+QString::number(blue,16));
00689 
00690     if (isLink)
00691         cell_style.appendChild(GetLinkStyle(gnumeric_doc));
00692 
00693     cell_style.appendChild(GetFontStyle(gnumeric_doc, cell, currentcolumn, currentrow));
00694 
00695     if ( cell->getValidity() )
00696     {
00697         cell_style.appendChild( GetValidity( gnumeric_doc, cell ) );
00698     }
00699 
00700     QString stringFormat;
00701 
00702  Format::Currency c;
00703     Currency currency;
00704 
00705     switch( cell->format()->getFormatType(currentcolumn, currentrow))
00706     {
00707         case Number_format:
00708             stringFormat="0.00";
00709             break;
00710         case Text_format:
00711             stringFormat="general";
00712             break;
00713         case Money_format:
00714 
00715             if (!cell->format()->currencyInfo(c))
00716             {
00717                 stringFormat = "0.00";
00718                 break;
00719             }
00720 
00721             if (currency.getCurrencyCode(c.type).isEmpty())
00722                 stringFormat = "0.00";
00723             else if (currency.getCurrencyCode(c.type) == "$")
00724                 stringFormat = "$0.00";
00725             else if (currency.getCurrencyCode(c.type) == QString::fromUtf8("€"))
00726                 stringFormat = "[$€-2]0.00";
00727             else if (currency.getCurrencyCode(c.type) == QString::fromUtf8("£"))
00728                 stringFormat = "£0.00";
00729             else if (currency.getCurrencyCode(c.type) == QString::fromUtf8("Â¥"))
00730                 stringFormat = "Â¥0.00";
00731             else
00732                 stringFormat="[$" + currency.getCurrencyCode(c.type) + "]0.00";
00733 
00734             break;
00735         case Percentage_format:
00736             stringFormat="0.00%";
00737             break;
00738         case Scientific_format:
00739             stringFormat="0.00E+00";
00740             break;
00741         case ShortDate_format:
00742             stringFormat=cell->locale()->dateFormatShort();
00743             break;
00744         case TextDate_format:
00745             stringFormat=cell->locale()->dateFormat();
00746             break;
00747         case date_format1:
00748             stringFormat="dd-mmm-yy";
00749             break;
00750         case date_format2:
00751             stringFormat="dd-mmm-yyyy";
00752             break;
00753         case date_format3:
00754             stringFormat="dd-mmm";
00755             break;
00756         case date_format4:
00757             stringFormat="dd-mm";
00758             break;
00759         case date_format5:
00760             stringFormat="dd/mm/yy";
00761             break;
00762         case date_format6:
00763             stringFormat="dd/mm/yyyy";
00764             break;
00765         case date_format7:
00766             stringFormat="mmm-yy";
00767             break;
00768         case date_format8:
00769             stringFormat="mmmm-yy";
00770             break;
00771         case date_format9:
00772             stringFormat="mmmm-yyyy";
00773             break;
00774         case date_format10:
00775             stringFormat="m-yy";
00776             break;
00777         case date_format11:
00778             stringFormat="dd/mmm";
00779             break;
00780         case date_format12:
00781             stringFormat="dd/mm";
00782             break;
00783         case date_format13:
00784             stringFormat="dd/mmm/yyyy";
00785             break;
00786         case date_format14:
00787             stringFormat="yyyy/mmm/dd";
00788             break;
00789         case date_format15:
00790             stringFormat="yyyy-mmm-dd";
00791             break;
00792         case date_format16:
00793             stringFormat="yyyy-mm-dd";
00794             break;
00795         case date_format17:
00796             stringFormat="d mmmm yyyy";
00797             break;
00798         case date_format18:
00799             stringFormat="mm/dd/yyyy";
00800             break;
00801         case date_format19:
00802             stringFormat="mm/dd/yy";
00803             break;
00804         case date_format20:
00805             stringFormat="mmm/dd/yy";
00806             break;
00807         case date_format21:
00808             stringFormat="mmm/dd/yyyy";
00809             break;
00810         case date_format22:
00811             stringFormat="mmm-yyyy";
00812             break;
00813         case date_format23:
00814             stringFormat="yyyy";
00815             break;
00816         case date_format24:
00817             stringFormat="yy";
00818             break;
00819         case date_format25:
00820             stringFormat="yyyy/mm/dd";
00821             break;
00822         case date_format26:
00823             stringFormat="yyyy/mmm/dd";
00824             break;
00825         case Time_format:
00826         case SecondeTime_format:
00827             stringFormat=cell->locale()->timeFormat();
00828             break;
00829         case Time_format1:
00830             stringFormat = "h:mm AM/PM";
00831             break;
00832         case Time_format2:
00833             stringFormat = "h:mm:ss AM/PM";
00834             break;
00835         case Time_format3:
00836             stringFormat = "h \"h\" mm \"min\" ss \"s\"";
00837             break;
00838         case Time_format4:
00839             stringFormat = "h:mm";
00840             break;
00841         case Time_format5:
00842             stringFormat = "h:mm:ss";
00843             break;
00844         case Time_format6:
00845             stringFormat = "mm:ss";
00846             break;
00847         case Time_format7:
00848             stringFormat = "[h]:mm:ss";
00849             break;
00850         case Time_format8:
00851             stringFormat = "[h]:mm";
00852             break;
00853         case fraction_half:
00854             stringFormat="# ?/2";
00855             break;
00856         case fraction_quarter:
00857             stringFormat="# ?/4";
00858             break;
00859         case fraction_eighth:
00860             stringFormat="# ?/8";
00861             break;
00862         case fraction_sixteenth:
00863             stringFormat="# ?/16";
00864             break;
00865         case fraction_tenth:
00866             stringFormat="# ?/10";
00867             break;
00868         case fraction_hundredth:
00869             stringFormat="# ?/100";
00870             break;
00871         case fraction_one_digit:
00872             stringFormat="# ?/?";
00873             break;
00874         case fraction_two_digits:
00875             stringFormat="# ?\?/?\?";
00876             break;
00877         case fraction_three_digits:
00878             stringFormat="# ?\?\?/?\?\?";
00879             break;
00880         case Custom_format:
00881             stringFormat = cell->format()->getFormatString(currentcolumn,currentrow);
00882             break;
00883         default:
00884             break;
00885     }
00886     cell_style.setAttribute("Format",stringFormat);
00887 
00888     if(hasBorder(cell, currentcolumn, currentrow))
00889         cell_style.appendChild(GetBorderStyle(gnumeric_doc, cell, currentcolumn, currentrow));
00890 
00891     return cell_style;
00892 }
00893 
00894 
00895 void GNUMERICExport::addAttributeItem(QDomDocument gnumeric_doc, QDomElement attributes, const QString& type, const QString& name, bool value)
00896 {
00897     QDomElement gmr_attribute, gmr_type, gmr_name, gmr_value;
00898 
00899     gmr_attribute = gnumeric_doc.createElement("gmr:Attribute");
00900     attributes.appendChild(gmr_attribute);
00901 
00902     gmr_type = gnumeric_doc.createElement("gmr:type");
00903     gmr_type.appendChild(gnumeric_doc.createTextNode(type));
00904     gmr_attribute.appendChild(gmr_type);
00905 
00906     gmr_name = gnumeric_doc.createElement("gmr:name");
00907     gmr_name.appendChild(gnumeric_doc.createTextNode(name));
00908     gmr_attribute.appendChild(gmr_name);
00909 
00910     QString txtValue;
00911     if (value)
00912         txtValue = "true";
00913     else
00914         txtValue = "false";
00915 
00916     gmr_value = gnumeric_doc.createElement("gmr:value");
00917     gmr_value.appendChild(gnumeric_doc.createTextNode(txtValue));
00918     gmr_attribute.appendChild(gmr_value);
00919 }
00920 
00921 void GNUMERICExport::addSummaryItem(QDomDocument gnumeric_doc, QDomElement summary, const QString& name, const QString& value)
00922 {
00923     if ( value.isEmpty() )
00924         return;
00925     QDomElement gmr_item, gmr_name, gmr_val_string;
00926 
00927     gmr_item = gnumeric_doc.createElement("gmr:Item");
00928     summary.appendChild(gmr_item);
00929 
00930     gmr_name = gnumeric_doc.createElement("gmr:name");
00931     gmr_name.appendChild(gnumeric_doc.createTextNode(name));
00932     gmr_item.appendChild(gmr_name);
00933 
00934     gmr_val_string = gnumeric_doc.createElement("gmr:val-string");
00935     gmr_val_string.appendChild(gnumeric_doc.createTextNode(value));
00936     gmr_item.appendChild(gmr_val_string);
00937 }
00938 
00939 // The reason why we use the KoDocument* approach and not the QDomDocument
00940 // approach is because we don't want to export formulas but values !
00941 KoFilter::ConversionStatus GNUMERICExport::convert( const QCString& from, const QCString& to )
00942 {
00943     kdDebug(30521) << "Exporting GNUmeric" << endl;
00944 
00945     QDomDocument gnumeric_doc=QDomDocument();
00946 
00947     Sheet* table;
00948     KoDocument* document = m_chain->inputDocument();
00949 
00950     if (!document)
00951         return KoFilter::StupidError;
00952 
00953     if ( !::qt_cast<const KSpread::Doc *>( document ) )  // it's safer that way :)
00954     {
00955       kdWarning(30521) << "document isn't a KSpread::Doc but a " << document->className() << endl;
00956         return KoFilter::NotImplemented;
00957     }
00958     if (to != "application/x-gnumeric" || from != "application/x-kspread")
00959     {
00960         kdWarning(30521) << "Invalid mimetypes " << to << " " << from << endl;
00961         return KoFilter::NotImplemented;
00962     }
00963 
00964     Doc* ksdoc = (Doc*)document;
00965 
00966     if (ksdoc->mimeType() != "application/x-kspread")
00967     {
00968         kdWarning(30521) << "Invalid document mimetype " << ksdoc->mimeType() << endl;
00969         return KoFilter::NotImplemented;
00970     }
00971 
00972     /* This could be Made into a function */
00973 
00974     gnumeric_doc.appendChild( gnumeric_doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
00975 
00976     QDomElement workbook = gnumeric_doc.createElement("gmr:Workbook");
00977     workbook.setAttribute("xmlns:gmr","http://www.gnumeric.org/v10.dtd");
00978     workbook.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
00979     workbook.setAttribute("xmlns:schemaLocation", "http://www.gnumeric.org/v8.xsd");
00980     gnumeric_doc.appendChild(workbook);
00981 
00982     /* End Made into a function */
00983 
00984     QDomElement sheets,sheet,tmp,cells,selections, cols,rows,styles,merged, margins, top, left, bottom, right, orientation, paper, header, footer, customSize, cellComment, objects, repeatColumns, repeatRows;
00985 
00986     KoDocumentInfo *DocumentInfo = document->documentInfo();
00987     KoDocumentInfoAbout *aboutPage = static_cast<KoDocumentInfoAbout *>(DocumentInfo->page( "about" ));
00988 
00989     KoDocumentInfoAuthor *authorPage = static_cast<KoDocumentInfoAuthor*>(DocumentInfo->page( "author" ));
00990 
00991     /*
00992      * Attributes
00993      */
00994     QDomElement attributes = gnumeric_doc.createElement("gmr:Attributes");
00995     workbook.appendChild(attributes);
00996 
00997     addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_horizontal_scrollbar", ksdoc->showHorizontalScrollBar());
00998     addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_vertical_scrollbar", ksdoc->showVerticalScrollBar());
00999     addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::show_notebook_tabs", ksdoc->showTabBar());
01000     if (ksdoc->completionMode() == KGlobalSettings::CompletionAuto)
01001         addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::do_auto_completion", "true");
01002     else
01003         addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::do_auto_completion", "false");
01004     addAttributeItem(gnumeric_doc, attributes, "4", "WorkbookView::is_protected", ksdoc->map()->isProtected());
01005 
01006     /*
01007      * Doccument summary
01008      */
01009     QDomElement summary =  gnumeric_doc.createElement("gmr:Summary");
01010     workbook.appendChild(summary);
01011 
01012     addSummaryItem(gnumeric_doc, summary, "title", aboutPage->title());
01013     addSummaryItem(gnumeric_doc, summary, "company", authorPage->company());
01014     addSummaryItem(gnumeric_doc, summary, "author", authorPage->fullName());
01015     addSummaryItem(gnumeric_doc, summary, "comments", aboutPage->abstract());
01016     addSummaryItem(gnumeric_doc, summary, "keywords", aboutPage->keywords());
01017 
01018     addSummaryItem(gnumeric_doc, summary, "application", "KSpread");
01019 
01020     /*
01021      * Sheet name index (necessary for the gnumeric xml_sax importer)
01022      */
01023     QDomElement sheetNameIndex = gnumeric_doc.createElement("gmr:SheetNameIndex");
01024     workbook.appendChild(sheetNameIndex);
01025 
01026     for (table = ksdoc->map()->firstSheet(); table != 0L; table =ksdoc->map()->nextSheet())
01027     {
01028         QDomElement sheetName = gnumeric_doc.createElement("gmr:SheetName");
01029         sheetName.appendChild(gnumeric_doc.createTextNode(table->tableName()));
01030         sheetNameIndex.appendChild(sheetName);
01031     }
01032 
01033     /*
01034      * Area Names
01035      */
01036     /*
01037     <gmr:Names>
01038     <gmr:Name>
01039       <gmr:name>test</gmr:name>
01040       <gmr:value>Sheet2!$A$2:$D$10</gmr:value>
01041       <gmr:position>A1</gmr:position>
01042     </gmr:Name>
01043     <gmr:Name>
01044       <gmr:name>voiture</gmr:name>
01045       <gmr:value>Sheet2!$A$2:$D$8</gmr:value>
01046       <gmr:position>A1</gmr:position>
01047     </gmr:Name>
01048   </gmr:Names>
01049     */
01050     if ( ksdoc->listArea().count()>0 )
01051     {
01052         QDomElement areaNames = gnumeric_doc.createElement("gmr:Names");
01053         const QValueList<Reference> &area = ksdoc->listArea(); // copying by value is slow!
01054         QValueList<Reference>::ConstIterator it = area.begin();
01055         QValueList<Reference>::ConstIterator end = area.end();
01056         for ( ; it != end; ++it )
01057         {
01058             QDomElement areaName = gnumeric_doc.createElement("gmr:Name");
01059             QDomElement areaNameElement = gnumeric_doc.createElement("gmr:name");
01060             areaNameElement.appendChild(gnumeric_doc.createTextNode(( *it ).ref_name) );
01061             areaName.appendChild( areaNameElement );
01062             QDomElement areaNameValue = gnumeric_doc.createElement("gmr:value");
01063             areaNameValue.appendChild(gnumeric_doc.createTextNode( convertRefToRange( ( *it ).sheet_name, ( *it ).rect )  ) );
01064             areaName.appendChild( areaNameValue );
01065             areaNames.appendChild( areaName );
01066             //TODO <gmr:position>A1</gmr:position> I don't know what is it.
01067         }
01068         workbook.appendChild(areaNames);
01069     }
01070 
01071 
01072     /*
01073      * Sheets
01074      */
01075     sheets = gnumeric_doc.createElement("gmr:Sheets");
01076     workbook.appendChild(sheets);
01077 
01078     QString str;
01079 
01080     View * view = static_cast<View*>( ksdoc->views().getFirst());
01081     Canvas * canvas=0L;
01082     QString activeTableName;
01083     if (view)
01084     {
01085         canvas = view->canvasWidget();
01086         activeTableName =  canvas->activeSheet()->sheetName();
01087     }
01088     int i = 0;
01089     int indexActiveTable=0;
01090     for (table = ksdoc->map()->firstSheet(); table != 0L; table =ksdoc->map()->nextSheet(), i++)
01091     {
01092         if ( table->print()->paperFormat()==PG_CUSTOM )
01093         {
01094             customSize = gnumeric_doc.createElement( "gmr:Geometry" );
01095             customSize.setAttribute( "Width", POINT_TO_MM ( table->print()->paperWidth() ));
01096             customSize.setAttribute( "Height", POINT_TO_MM (table->print()->paperWidth() ));
01097             sheets.appendChild(customSize);
01098             //<gmr:Geometry Width="768" Height="365"/>
01099         }
01100 
01101         sheet = gnumeric_doc.createElement("gmr:Sheet");
01102         sheets.appendChild(sheet);
01103 
01104         sheet.setAttribute("DisplayFormulas", table->getShowFormula() ? "true" : "false" );
01105         sheet.setAttribute("HideZero", table->getHideZero()? "true" : "false");
01106         sheet.setAttribute("HideGrid", !table->getShowGrid()? "true" : "false");
01107         sheet.setAttribute("HideColHeader", ( !ksdoc->showColumnHeader() ? "true" : "false" ));
01108         sheet.setAttribute("HideRowHeader", ( !ksdoc->showRowHeader()? "true" : "false" ));
01109         /* Not available in KSpread ?
01110          * sheet.setAttribute("DisplayOutlines", "true");
01111          * sheet.setAttribute("OutlineSymbolsBelow", "true");
01112          * sheet.setAttribute("OutlineSymbolsRight", "true");
01113          * sheet.setAttribute("TabColor", "");
01114          * sheet.setAttribute("TabTextColor", "");
01115          */
01116 
01117         tmp = gnumeric_doc.createElement("gmr:Name");
01118         if ( table->tableName()==activeTableName )
01119             indexActiveTable = i;
01120 
01121         tmp.appendChild(gnumeric_doc.createTextNode(table->tableName()));
01122 
01123         sheet.appendChild(tmp);
01124 
01125         tmp = gnumeric_doc.createElement("gmr:MaxCol");
01126         tmp.appendChild(gnumeric_doc.createTextNode(QString::number(table->maxColumn())));
01127         sheet.appendChild(tmp);
01128 
01129         tmp = gnumeric_doc.createElement("gmr:MaxRow");
01130 
01131         tmp.appendChild(gnumeric_doc.createTextNode(QString::number(table->maxRow())));
01132         sheet.appendChild(tmp);
01133 
01134         // Zoom value doesn't appear to be correct
01135         // KSpread 200% gives zoom() = 2.5, this in GNumeric = 250%
01136         tmp = gnumeric_doc.createElement("gmr:Zoom");
01137         if (view)
01138             tmp.appendChild(gnumeric_doc.createTextNode(QString::number(canvas->zoom())));
01139         else
01140             tmp.appendChild(gnumeric_doc.createTextNode("1.0"));
01141         sheet.appendChild(tmp);
01142 
01143         //Print Info
01144         tmp = gnumeric_doc.createElement( "gmr:PrintInformation" );
01145         margins = gnumeric_doc.createElement( "gmr:Margins" );
01146 
01147         top = gnumeric_doc.createElement( "gmr:top" );
01148         top.setAttribute("Points", table->print()->topBorder());
01149         top.setAttribute("PrefUnit", "mm");
01150         margins.appendChild( top );
01151 
01152         bottom = gnumeric_doc.createElement( "gmr:bottom" );
01153         bottom.setAttribute("Points", table->print()->bottomBorder());
01154         bottom.setAttribute("PrefUnit", "mm");
01155         margins.appendChild( bottom );
01156 
01157         left = gnumeric_doc.createElement( "gmr:left" );
01158         left.setAttribute("Points", table->print()->leftBorder());
01159         left.setAttribute("PrefUnit", "mm");
01160         margins.appendChild( left );
01161 
01162         right = gnumeric_doc.createElement( "gmr:right" );
01163         right.setAttribute("Points", table->print()->rightBorder());
01164         right.setAttribute("PrefUnit", "mm");
01165         margins.appendChild( right );
01166 
01167         tmp.appendChild( margins );
01168         sheet.appendChild(tmp);
01169 
01170         orientation = gnumeric_doc.createElement( "gmr:orientation" );
01171         QString orientString = table->print()->orientation() == PG_LANDSCAPE ? "landscape" : "portrait";
01172         orientation.appendChild( gnumeric_doc.createTextNode(orientString) );
01173         tmp.appendChild( orientation );
01174 
01175         //TODO for future
01176         //<gmr:repeat_top value="A1:IV5"/>
01177         //<gmr:repeat_left value="B1:D65536"/>
01178 
01179         int _tmpRepeatColumnStart = table->print()->printRepeatColumns().first;
01180         int _tmpRepeatColumnEnd = table->print()->printRepeatColumns().second;
01181         if ( _tmpRepeatColumnStart!=0 )
01182         {
01183             repeatColumns = gnumeric_doc.createElement( "gmr:repeat_left" );
01184             QString value = Cell::columnName( _tmpRepeatColumnStart )+"1:"+Cell::columnName(_tmpRepeatColumnEnd )+"65536";
01185             repeatColumns.setAttribute( "value", value );
01186             tmp.appendChild( repeatColumns );
01187         }
01188         int _tmpRepeatRowStart = table->print()->printRepeatRows().first;
01189         int _tmpRepeatRowEnd = table->print()->printRepeatRows().second;
01190         if ( _tmpRepeatRowStart!=0 )
01191         {
01192             repeatRows = gnumeric_doc.createElement( "gmr:repeat_top" );
01193             QString value = "A"+ QString::number(_tmpRepeatRowStart ) +":IV"+QString::number( _tmpRepeatRowEnd );
01194             repeatRows.setAttribute( "value", value );
01195             tmp.appendChild( repeatRows );
01196         }
01197 
01198         header = gnumeric_doc.createElement( "gmr:Header" );
01199         header.setAttribute( "Left", convertVariable(table->print()->headLeft() ) );
01200         header.setAttribute( "Middle", convertVariable(table->print()->headMid() ) );
01201         header.setAttribute( "Right", convertVariable(table->print()->headRight() ) );
01202         tmp.appendChild( header );
01203 
01204         footer = gnumeric_doc.createElement( "gmr:Footer" );
01205         footer.setAttribute( "Left", convertVariable( table->print()->footLeft() ) );
01206         footer.setAttribute( "Middle", convertVariable( table->print()->footMid() ) );
01207         footer.setAttribute( "Right", convertVariable( table->print()->footRight() ));
01208         tmp.appendChild( footer );
01209 
01210         paper = gnumeric_doc.createElement( "gmr:paper" );
01211         paper.appendChild( gnumeric_doc.createTextNode( table->print()->paperFormatString() ) );
01212         tmp.appendChild( paper );
01213 
01214         styles = gnumeric_doc.createElement("gmr:Styles");
01215         sheet.appendChild(styles);
01216 
01217         cells = gnumeric_doc.createElement("gmr:Cells");
01218         sheet.appendChild(cells);
01219 
01220         objects = gnumeric_doc.createElement("gmr:Objects");
01221         sheet.appendChild(objects);
01222 
01223         merged = gnumeric_doc.createElement("gmr:MergedRegions");
01224         bool mergedCells = false; // if there are no merged cells in this sheet, don't write an
01225         // empty mergedRegions to the file.
01226         // So, depending on the value of mergedCells,
01227         // the merged dom element is added or not.
01228 
01229         cols = gnumeric_doc.createElement("gmr:Cols");
01230         sheet.appendChild(cols);
01231 
01232         rows = gnumeric_doc.createElement("gmr:Rows");
01233         sheet.appendChild(rows);
01234 
01235         /*
01236           selections = gnumeric_doc.createElement("gmr:Selections");
01237           sheet.appendChild(selections);
01238         */
01239         // Ah ah ah - the document is const, but the map and table aren't. Safety: 0.
01240         // Either we get hold of Sheet::m_dctCells and apply the old method below
01241         // (for sorting) or, cleaner and already sorted, we use Sheet's API
01242         // (slower probably, though)
01243         int iMaxColumn = table->maxColumn();
01244         int iMaxRow = table->maxRow();
01245 
01246         // this is just a bad approximation which fails for documents with less than 50 rows, but
01247         // we don't need any progress stuff there anyway :) (Werner)
01248         int value=0;
01249         int step=iMaxRow > 50 ? iMaxRow/50 : 1;
01250         int i=1;
01251 
01252         QString emptyLines;
01253 
01254         /* Save selection info. */
01255 
01256         /* can't save selection anymore -- part of the view, not table */
01257         /*
01258           QDomElement selection = gnumeric_doc.createElement("gmr:Selection");
01259           QRect table_selection(table->selection());
01260 
01261           selections.appendChild(selection);
01262         */
01263         /*  <gmr:Selection startCol="3" startRow="2" endCol="3" endRow="2"/>*/
01264         /*
01265           selection.setAttribute("startCol", QString::number(table_selection.left()-1));
01266           selection.setAttribute("startRow", QString::number(table_selection.top()-1));
01267 
01268           selection.setAttribute("endCol", QString::number(table_selection.right()-1));
01269           selection.setAttribute("endRow", QString::number(table_selection.bottom()-1));
01270         */
01271         /* End selection info. */
01272 
01273 
01274         /* Start COLS */
01275         ColumnFormat *cl=table->firstCol();
01276         while (cl)
01277         {
01278             QDomElement colinfo = gnumeric_doc.createElement("gmr:ColInfo");
01279             cols.appendChild(colinfo);
01280             colinfo.setAttribute("No", QString::number(cl->column()-1));
01281             colinfo.setAttribute("Hidden", QString::number(cl->isHide()));
01282             colinfo.setAttribute("Unit", QString::number(cl->dblWidth()));
01283 
01284             cl=cl->next();
01285         }
01286 
01287         /* End COLS */
01288 
01289         //   RowFormat *rl=table->m_cells.firstCell;
01290         //   <gmr:ColInfo No="1" Unit="96.75" MarginA="2" MarginB="2" HardSize="-1" Hidden="0"/>
01291 
01292         /* Start ROWS */
01293         RowFormat *rl=table->firstRow();
01294         while (rl)
01295         {
01296             QDomElement rowinfo = gnumeric_doc.createElement("gmr:RowInfo");
01297             rows.appendChild(rowinfo);
01298             rowinfo.setAttribute("No", QString::number(rl->row()-1));
01299             rowinfo.setAttribute("Hidden", QString::number(rl->isHide()));
01300             rowinfo.setAttribute("Unit", QString::number(rl->dblHeight()));
01301 
01302             rl=rl->next();
01303         }
01304 
01305         /* End ROWS */
01306 
01307         //rl->setHeight
01308         //   colinfo.info();
01309         /*
01310           <gmr:ColInfo No="1" Unit="96.75" MarginA="2" MarginB="2" HardSize="-1" Hidden="0"/>
01311           <gmr:ColInfo No="3" Unit="113.25" MarginA="2" MarginB="2" HardSize="-1"
01312           Hidden="0"/>
01313         */
01314 
01315         /* End COLS */
01316 
01317         for (int currentrow = 1; currentrow <= iMaxRow; ++currentrow, ++i)
01318         {
01319             if(i>step)
01320             {
01321                 value+=2;
01322                 emit sigProgress(value);
01323                 i=0;
01324             }
01325 
01326             QString line;
01327             for (int currentcolumn = 1; currentcolumn <= iMaxColumn; currentcolumn++)
01328             {
01329                 QDomElement cell_contents;
01330                 Cell * cell = table->cellAt( currentcolumn, currentrow, false );
01331 
01332                 QString text, style;
01333                 QDomDocument domLink;
01334                 QDomElement domRoot;
01335                 QDomNode domNode;
01336                 QDomNodeList childNodes;
01337 
01338                 if (!cell->isDefault() && !cell->isEmpty())
01339                 {
01340                     if ( cell->isFormula() )
01341                     {
01342                         QString tmp = cell->text();
01343                         if ( tmp.contains( "==" ) )
01344                             tmp=tmp.replace( "==", "=" );
01345                         text = tmp;
01346                         isLink = false;
01347                     }
01348                     else if ( !cell->link().isEmpty() )
01349                     {
01350                         isLink = true;
01351                         isLinkBold = false;
01352                         isLinkItalic = false;
01353                         //TODO FIXME
01354                         linkUrl = cell->link();
01355                         linkText = cell->text();
01356 
01357                     }
01358                     else
01359                     {
01360                         text = cell->text();
01361                         isLink = false;
01362                     }
01363 #if 0
01364                     switch (cell->content())
01365                     {
01366                     case Cell::Text:
01367                         text = cell->text();
01368                         isLink = false;
01369                         break;
01370                     case Cell::RichText:
01371                         // hyperlinks
01372                         // Extract the cell text
01373                         isLink = true;
01374                         isLinkBold = false;
01375                         isLinkItalic = false;
01376                         domLink.setContent(cell->text().section("!",1,1));
01377 
01378                         domNode = domLink.firstChild();
01379                         domRoot = domNode.toElement();
01380                         text = domNode.toElement().text();
01381 
01382                         while (!domNode.isNull())
01383                         {
01384                             style = domNode.toElement().tagName();
01385 
01386                             if (style == "b")
01387                                 isLinkBold = true;
01388 
01389                             if (style == "i")
01390                                 isLinkItalic = true;
01391 
01392                             domNode = domNode.firstChild();
01393                         }
01394 
01395                         //kdDebug(30521) << "---> link, text = " << text << endl;
01396 
01397                         linkUrl = domRoot.attribute("href");
01398                         linkText = text;
01399 
01400                         break;
01401                     case Cell::VisualFormula:
01402                         isLink = false;
01403                         text = cell->text(); // untested
01404                         break;
01405                     case Cell::Formula:
01406                         isLink = false;
01407                         QString tmp = cell->text();
01408                         if ( tmp =="==" )
01409                             tmp=replace( "==", "=" );
01410                         /* cell->calc( TRUE ); // Incredible, cells are not calculated if the document was just opened text = cell->valueString(); */
01411                         text = tmp;
01412                         break;
01413                     }
01414 #endif
01415                 }
01416 
01417                 if (!cell->isDefault())
01418                 {
01419 
01420                     // Check if the cell is merged
01421                     // Only cells with content are interesting?
01422                     // Otherwise it can take a while to parse a large sheet
01423 
01424                     if (cell->doesMergeCells())
01425                     {
01426                         // The cell is forced to occupy other cells
01427                         QDomElement merge = gnumeric_doc.createElement("gmr:Merge");
01428 
01429                         // Set up the range
01430                         QString fromCol, toCol, fromRow, toRow;
01431                         fromCol = cell->columnName(currentcolumn);
01432                         fromRow = QString::number(currentrow);
01433                         toCol = cell->columnName(currentcolumn + cell->mergedXCells());
01434                         toRow = QString::number(currentrow + cell->mergedYCells());
01435 
01436                         merge.appendChild(gnumeric_doc.createTextNode(fromCol + fromRow + ":" + toCol + toRow));
01437                         mergedCells = true;
01438                         merged.appendChild(merge);
01439                     }
01440                     // ---
01441                     if ( !cell->format()->comment( currentcolumn, currentrow ).isEmpty() )
01442                     {
01443                         //<gmr:CellComment Author="" Text="cvbcvbxcvb&#10;cb&#10;xc&#10;vbxcv&#10;" ObjectBound="A1" ObjectOffset="0 0 0 0" ObjectAnchorType="17 16 17 16" Direction="17"/>
01444                         cellComment = gnumeric_doc.createElement("gmr:CellComment");
01445                         cellComment.setAttribute( "Text", cell->format()->comment( currentcolumn, currentrow ) );
01446                         QString sCell=QString( "%1%2" ).arg( Cell::columnName(currentcolumn ) ).arg( currentrow );
01447 
01448                         cellComment.setAttribute("ObjectBound", sCell );
01449                         objects.appendChild(cellComment);
01450 
01451                     }
01452                     QDomElement gnumeric_cell = gnumeric_doc.createElement("gmr:Cell");
01453                     QDomElement cell_style;
01454 
01455                     QDomElement style_region = gnumeric_doc.createElement("gmr:StyleRegion");
01456 
01457                     cells.appendChild(gnumeric_cell);
01458 
01459                     gnumeric_cell.setAttribute("Col", QString::number(currentcolumn-1));
01460                     gnumeric_cell.setAttribute("Row", QString::number(currentrow-1));
01461 
01462                     /* Right now, we create a single region for each cell.. This is inefficient,
01463                      * but the implementation is quicker.. Probably later we will have to
01464                      * consolidate styles into style regions.
01465                      */
01466 
01467                     style_region.setAttribute("startCol", QString::number(currentcolumn-1));
01468                     style_region.setAttribute("startRow", QString::number(currentrow-1));
01469                     style_region.setAttribute("endCol", QString::number(currentcolumn-1));
01470                     style_region.setAttribute("endRow", QString::number(currentrow-1));
01471 
01472                     cell_style = GetCellStyle(gnumeric_doc,cell,currentcolumn,currentrow);
01473 
01474                     style_region.appendChild(cell_style);
01475 
01476                     styles.appendChild(style_region);
01477 
01478                     //cell_contents = gnumeric_doc.createElement("gmr:Content");
01479                     gnumeric_cell.appendChild(gnumeric_doc.createTextNode(text));
01480                     //gnumeric_cell.appendChild(cell_contents);
01481                 }
01482 
01483                 // Append a delimiter, but in a temp string -> if no other real cell in this line,
01484                 // then those will be dropped
01485             }
01486         }
01487 
01488         if (mergedCells)
01489             sheet.appendChild(merged);
01490     }
01491     QDomElement uidata = gnumeric_doc.createElement("gmr:UIData");
01492     uidata.setAttribute( "SelectedTab", indexActiveTable );
01493     workbook.appendChild(uidata);
01494 
01495     str = gnumeric_doc.toString ();
01496 
01497     emit sigProgress(100);
01498 
01499     // Ok, now write to export file
01500 
01501     QIODevice* out = KFilterDev::deviceForFile(m_chain->outputFile(),"application/x-gzip");
01502 
01503     if (!out)
01504     {
01505         kdError(30521) << "No output file! Aborting!" << endl;
01506         return KoFilter::FileNotFound;
01507     }
01508 
01509     if (!out->open(IO_WriteOnly))
01510     {
01511         kdError(30521) << "Unable to open output file! Aborting!" << endl;
01512         delete out;
01513         return KoFilter::FileNotFound;
01514     }
01515 
01516     QTextStream streamOut(out);
01517 
01518     streamOut << str;
01519 
01520     out->close();
01521     delete out;
01522 
01523     return KoFilter::OK;
01524 }
01525 
01526 
01527 QString GNUMERICExport::convertRefToRange( const QString & table, const QRect & rect )
01528 {
01529   QPoint topLeft( rect.topLeft() );
01530   QPoint bottomRight( rect.bottomRight() );
01531   if ( topLeft == bottomRight )
01532     return convertRefToBase( table, rect );
01533   QString s;
01534   s += table;
01535   s += "!$";
01536   s += Cell::columnName( topLeft.x() );
01537   s += '$';
01538   s += QString::number( topLeft.y() );
01539   s += ":$";
01540   s += Cell::columnName( bottomRight.x() );
01541   s += '$';
01542   s += QString::number( bottomRight.y() );
01543 
01544   return s;
01545 }
01546 
01547 
01548 QString GNUMERICExport::convertRefToBase( const QString & table, const QRect & rect )
01549 {
01550   QPoint bottomRight( rect.bottomRight() );
01551 
01552   QString s;
01553   s = table;
01554   s += "!$";
01555   s += Cell::columnName( bottomRight.x() );
01556   s += '$';
01557   s += QString::number( bottomRight.y() );
01558 
01559   return s;
01560 }
01561 
01562 QString GNUMERICExport::convertVariable( QString headerFooter )
01563 {
01564     headerFooter = headerFooter.replace( "<sheet>", "&[TAB]" );
01565     headerFooter = headerFooter.replace( "<date>", "&[DATE]" );
01566     headerFooter = headerFooter.replace( "<page>", "&[PAGE]" );
01567     headerFooter = headerFooter.replace( "<pages>", "&[PAGES]" );
01568     headerFooter = headerFooter.replace( "<time>", "&[TIME]" );
01569     headerFooter = headerFooter.replace( "<file>", "&[FILE]" );
01570 
01571     return headerFooter;
01572 }
01573 
01574 #include "gnumericexport.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys