filters

ooutils.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com>
00003    Copyright (c) 2003 Lukas Tinkl <lukas@kde.org>
00004    Copyright (c) 2003 David Faure <faure@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "ooutils.h"
00023 #include <KoDocument.h>
00024 #include <KoStyleStack.h>
00025 #include <qdom.h>
00026 #include <qcolor.h>
00027 #include <qimage.h>
00028 #include <KoUnit.h>
00029 #include <qregexp.h>
00030 #include <kdebug.h>
00031 #include <kzip.h>
00032 #include <KoDom.h>
00033 #include <qxml.h>
00034 
00035 const char* const ooNS::office="http://openoffice.org/2000/office";
00036 const char* const ooNS::style="http://openoffice.org/2000/style";
00037 const char* const ooNS::text="http://openoffice.org/2000/text";
00038 const char* const ooNS::table="http://openoffice.org/2000/table";
00039 const char* const ooNS::draw="http://openoffice.org/2000/drawing";
00040 const char* const ooNS::presentation="http://openoffice.org/2000/presentation";
00041 const char* const ooNS::fo="http://www.w3.org/1999/XSL/Format";
00042 const char* const ooNS::xlink="http://www.w3.org/1999/xlink";
00043 const char* const ooNS::number="http://openoffice.org/2000/datastyle";
00044 const char* const ooNS::svg="http://www.w3.org/2000/svg";
00045 const char* const ooNS::dc="http://purl.org/dc/elements/1.1/";
00046 const char* const ooNS::meta="http://openoffice.org/2000/meta";
00047 const char* const ooNS::config="http://openoffice.org/2001/config";
00048 
00049 QString OoUtils::expandWhitespace(const QDomElement& tag)
00050 {
00051     //tags like <text:s text:c="4">
00052 
00053     int howmany=1;
00054     if (tag.hasAttributeNS( ooNS::text, "c"))
00055         howmany = tag.attributeNS( ooNS::text, "c", QString::null).toInt();
00056 
00057     QString result;
00058     return result.fill(32, howmany);
00059 }
00060 
00061 bool OoUtils::parseBorder(const QString & tag, double * width, int * style, QColor * color)
00062 {
00063     //string like "0.088cm solid #800000"
00064 
00065     if (tag.isEmpty() || tag=="none" || tag=="hidden") // in fact no border
00066         return false;
00067 
00068     QString _width = tag.section(' ', 0, 0);
00069     QString _style = tag.section(' ', 1, 1);
00070     QString _color = tag.section(' ', 2, 2);
00071 
00072     *width = KoUnit::parseValue(_width, 1.0);
00073 
00074     if ( _style == "dashed" )
00075         *style = 1;
00076     else if ( _style == "dotted" )
00077         *style = 2;
00078     else if ( _style == "dot-dash" ) // not in xsl/fo, but in OASIS (in other places)
00079         *style = 3;
00080     else if ( _style == "dot-dot-dash" ) // not in xsl/fo, but in OASIS (in other places)
00081         *style = 4;
00082     else if ( _style == "double" )
00083         *style = 5;
00084     else
00085         *style = 0;
00086 
00087     if (_color.isEmpty())
00088         *color = QColor();
00089     else
00090         color->setNamedColor(_color);
00091 
00092     return true;
00093 }
00094 
00095 void OoUtils::importIndents( QDomElement& parentElement, const KoStyleStack& styleStack )
00096 {
00097     if ( styleStack.hasAttributeNS( ooNS::fo, "margin-left" ) || // 3.11.19
00098          styleStack.hasAttributeNS( ooNS::fo, "margin-right" ) )
00099          // *text-indent must always be bound to either margin-left or margin-right
00100     {
00101         double marginLeft = KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-left" ) );
00102         double marginRight = KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-right" ) );
00103         double first = 0;
00104         if (styleStack.attributeNS( ooNS::style, "auto-text-indent") == "true") // style:auto-text-indent takes precedence
00105             // ### "indented by a value that is based on the current font size"
00106             // ### and "requires margin-left and margin-right
00107             // ### but how much is the indent?
00108             first = 10;
00109         else if (styleStack.hasAttributeNS( ooNS::fo, "text-indent"))
00110             first = KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "text-indent"));
00111 
00112         if ( marginLeft != 0 || marginRight != 0 || first != 0 )
00113         {
00114             QDomElement indent = parentElement.ownerDocument().createElement( "INDENTS" );
00115             if( marginLeft != 0 )
00116                 indent.setAttribute( "left", marginLeft );
00117             if( marginRight != 0 )
00118                 indent.setAttribute( "right", marginRight );
00119             if( first != 0 )
00120                 indent.setAttribute( "first", first );
00121             parentElement.appendChild( indent );
00122         }
00123     }
00124 }
00125 
00126 void OoUtils::importLineSpacing( QDomElement& parentElement, const KoStyleStack& styleStack )
00127 {
00128     if( styleStack.hasAttributeNS( ooNS::fo, "line-height") )
00129     {
00130         // Fixed line height
00131         QString value = styleStack.attributeNS( ooNS::fo, "line-height" ); // 3.11.1
00132         if ( value != "normal" )
00133         {
00134             QDomElement lineSpacing = parentElement.ownerDocument().createElement( "LINESPACING" );
00135 
00136             if ( value.endsWith("%" ) )
00137             {
00138                 double percent = value.left(value.length()-1).toDouble();
00139                 if( percent == 100 )
00140                     lineSpacing.setAttribute("type","single");
00141                 else if( percent == 150 )
00142                     lineSpacing.setAttribute("type","oneandhalf");
00143                 else if( percent == 200 )
00144                     lineSpacing.setAttribute("type","double");
00145                 else
00146                 {
00147                   lineSpacing.setAttribute("type", "multiple");
00148                   lineSpacing.setAttribute("spacingvalue", percent/100);
00149                 }
00150             }
00151             else // fixed value (TODO use KoUnit::parseValue to get it in pt)
00152             {
00153                 kdWarning(30519) << "Unhandled value for fo:line-height: " << value << endl;
00154                 lineSpacing.setAttribute("type","single"); // fallback
00155             }
00156             parentElement.appendChild( lineSpacing );
00157         }
00158     }
00159     // Line-height-at-least is mutually exclusive with line-height
00160     else if ( styleStack.hasAttributeNS( ooNS::style, "line-height-at-least") ) // 3.11.2
00161     {
00162         QString value = styleStack.attributeNS( ooNS::style, "line-height-at-least" );
00163         // kotext has "at least" but that's for the linespacing, not for the entire line height!
00164         // Strange. kotext also has "at least" for the whole line height....
00165         // Did we make the wrong choice in kotext?
00166         //kdWarning(30519) << "Unimplemented support for style:line-height-at-least: " << value << endl;
00167         // Well let's see if this makes a big difference.
00168         QDomElement lineSpacing = parentElement.ownerDocument().createElement("LINESPACING");
00169         lineSpacing.setAttribute("type", "atleast");
00170         lineSpacing.setAttribute("spacingvalue", KoUnit::parseValue(value));
00171         parentElement.appendChild(lineSpacing);
00172     }
00173     // Line-spacing is mutually exclusive with line-height and line-height-at-least
00174     else if ( styleStack.hasAttributeNS( ooNS::style, "line-spacing") ) // 3.11.3
00175     {
00176         double value = KoUnit::parseValue( styleStack.attributeNS( ooNS::style, "line-spacing" ) );
00177         if ( value != 0.0 )
00178         {
00179             QDomElement lineSpacing = parentElement.ownerDocument().createElement( "LINESPACING" );
00180             lineSpacing.setAttribute( "type", "custom" );
00181             lineSpacing.setAttribute( "spacingvalue", value );
00182             parentElement.appendChild( lineSpacing );
00183         }
00184     }
00185 
00186 }
00187 
00188 void OoUtils::importTopBottomMargin( QDomElement& parentElement, const KoStyleStack& styleStack )
00189 {
00190     if( styleStack.hasAttributeNS( ooNS::fo, "margin-top") || // 3.11.22
00191         styleStack.hasAttributeNS( ooNS::fo, "margin-bottom"))
00192     {
00193         double mtop = KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-top" ) );
00194         double mbottom = KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-bottom" ) );
00195         if( mtop != 0 || mbottom != 0 )
00196         {
00197             QDomElement offset = parentElement.ownerDocument().createElement( "OFFSETS" );
00198             if( mtop != 0 )
00199                 offset.setAttribute( "before", mtop );
00200             if( mbottom != 0 )
00201                 offset.setAttribute( "after", mbottom );
00202             parentElement.appendChild( offset );
00203         }
00204     }
00205 }
00206 
00207 void OoUtils::importTabulators( QDomElement& parentElement, const KoStyleStack& styleStack )
00208 {
00209     if ( !styleStack.hasChildNodeNS( ooNS::style, "tab-stops" ) ) // 3.11.10
00210         return;
00211     QDomElement tabStops = styleStack.childNodeNS( ooNS::style, "tab-stops" );
00212     //kdDebug(30519) << k_funcinfo << tabStops.childNodes().count() << " tab stops in layout." << endl;
00213     for ( QDomNode it = tabStops.firstChild(); !it.isNull(); it = it.nextSibling() )
00214     {
00215         QDomElement tabStop = it.toElement();
00216         Q_ASSERT( tabStop.tagName() == "style:tab-stop" );
00217         QString type = tabStop.attributeNS( ooNS::style, "type", QString::null ); // left, right, center or char
00218 
00219         QDomElement elem = parentElement.ownerDocument().createElement( "TABULATOR" );
00220         int kOfficeType = 0;
00221         if ( type == "left" )
00222             kOfficeType = 0;
00223         else if ( type == "center" )
00224             kOfficeType = 1;
00225         else if ( type == "right" )
00226             kOfficeType = 2;
00227         else if ( type == "char" ) {
00228             QString delimiterChar = tabStop.attributeNS( ooNS::style, "char", QString::null ); // single character
00229             elem.setAttribute( "alignchar", delimiterChar );
00230             kOfficeType = 3; // "alignment on decimal point"
00231         }
00232 
00233         elem.setAttribute( "type", kOfficeType );
00234 
00235         double pos = KoUnit::parseValue( tabStop.attributeNS( ooNS::style, "position", QString::null ) );
00236         elem.setAttribute( "ptpos", pos );
00237 
00238         // TODO Convert leaderChar's unicode value to the KOffice enum
00239         // (blank/dots/line/dash/dash-dot/dash-dot-dot, 0 to 5)
00240         QString leaderChar = tabStop.attributeNS( ooNS::style, "leader-char", QString::null ); // single character
00241         if ( !leaderChar.isEmpty() )
00242         {
00243             int filling = 0;
00244             QChar ch = leaderChar[0];
00245             switch (ch.latin1()) {
00246             case '.':
00247                 filling = 1; break;
00248             case '-':
00249             case '_':  // TODO in KWord: differentiate --- and ___
00250                 filling = 2; break;
00251             default:
00252                 // KWord doesn't have support for "any char" as filling.
00253                 // Instead it has dash-dot and dash-dot-dot - but who uses that in a tabstop?
00254                 break;
00255             }
00256             elem.setAttribute( "filling", filling );
00257         }
00258         parentElement.appendChild( elem );
00259     }
00260 
00261 }
00262 
00263 void OoUtils::importBorders( QDomElement& parentElement, const KoStyleStack& styleStack )
00264 {
00265     if (styleStack.hasAttributeNS( ooNS::fo, "border","left"))
00266     {
00267         double width;
00268         int style;
00269         QColor color;
00270         if (OoUtils::parseBorder(styleStack.attributeNS( ooNS::fo, "border", "left"), &width, &style, &color))
00271         {
00272             QDomElement lbElem = parentElement.ownerDocument().createElement("LEFTBORDER");
00273             lbElem.setAttribute("width", width);
00274             lbElem.setAttribute("style", style);
00275             if (color.isValid()) {
00276                 lbElem.setAttribute("red", color.red());
00277                 lbElem.setAttribute("green", color.green());
00278                 lbElem.setAttribute("blue", color.blue());
00279             }
00280             parentElement.appendChild(lbElem);
00281         }
00282     }
00283 
00284     if (styleStack.hasAttributeNS( ooNS::fo, "border", "right"))
00285     {
00286         double width;
00287         int style;
00288         QColor color;
00289         if (OoUtils::parseBorder(styleStack.attributeNS( ooNS::fo, "border", "right"), &width, &style, &color))
00290         {
00291             QDomElement lbElem = parentElement.ownerDocument().createElement("RIGHTBORDER");
00292             lbElem.setAttribute("width", width);
00293             lbElem.setAttribute("style", style);
00294             if (color.isValid()) {
00295                 lbElem.setAttribute("red", color.red());
00296                 lbElem.setAttribute("green", color.green());
00297                 lbElem.setAttribute("blue", color.blue());
00298             }
00299             parentElement.appendChild(lbElem);
00300         }
00301     }
00302 
00303     if (styleStack.hasAttributeNS( ooNS::fo, "border", "top"))
00304     {
00305         double width;
00306         int style;
00307         QColor color;
00308         if (OoUtils::parseBorder(styleStack.attributeNS( ooNS::fo, "border", "top"), &width, &style, &color))
00309         {
00310             QDomElement lbElem = parentElement.ownerDocument().createElement("TOPBORDER");
00311             lbElem.setAttribute("width", width);
00312             lbElem.setAttribute("style", style);
00313             if (color.isValid()) {
00314                 lbElem.setAttribute("red", color.red());
00315                 lbElem.setAttribute("green", color.green());
00316                 lbElem.setAttribute("blue", color.blue());
00317             }
00318             parentElement.appendChild(lbElem);
00319         }
00320     }
00321 
00322     if (styleStack.hasAttributeNS( ooNS::fo, "border", "bottom"))
00323     {
00324         double width;
00325         int style;
00326         QColor color;
00327         if (OoUtils::parseBorder(styleStack.attributeNS( ooNS::fo, "border", "bottom"), &width, &style, &color))
00328         {
00329             QDomElement lbElem = parentElement.ownerDocument().createElement("BOTTOMBORDER");
00330             lbElem.setAttribute("width", width);
00331             lbElem.setAttribute("style", style);
00332             if (color.isValid()) {
00333                 lbElem.setAttribute("red", color.red());
00334                 lbElem.setAttribute("green", color.green());
00335                 lbElem.setAttribute("blue", color.blue());
00336             }
00337             parentElement.appendChild(lbElem);
00338         }
00339     }
00340 }
00341 
00342 void OoUtils::importUnderline( const QString& in, QString& underline, QString& styleline )
00343 {
00344     underline = "single";
00345     if ( in == "none" )
00346         underline = "0";
00347     else if ( in == "single" )
00348         styleline = "solid";
00349     else if ( in == "double" )
00350     {
00351         underline = in;
00352         styleline = "solid";
00353     }
00354     else if ( in == "dotted" || in == "bold-dotted" ) // bold-dotted not in libkotext
00355         styleline = "dot";
00356     else if ( in == "dash"
00357               // those are not in libkotext:
00358               || in == "long-dash"
00359               || in == "bold-dash"
00360               || in == "bold-long-dash"
00361         )
00362         styleline = "dash";
00363     else if ( in == "dot-dash"
00364               || in == "bold-dot-dash") // not in libkotext
00365         styleline = "dashdot"; // tricky ;)
00366     else if ( in == "dot-dot-dash"
00367               || in == "bold-dot-dot-dash") // not in libkotext
00368         styleline = "dashdotdot"; // this is getting fun...
00369     else if ( in == "wave"
00370               || in == "bold-wave" // not in libkotext
00371               || in == "double-wave" // not in libkotext
00372               || in == "small-wave" ) // not in libkotext
00373     {
00374         underline = in;
00375         styleline = "solid";
00376     }
00377     else if( in == "bold" )
00378     {
00379         underline = "single-bold";
00380         styleline = "solid";
00381     }
00382     else
00383         kdWarning(30519) << k_funcinfo << " unsupported text-underline value: " << in << endl;
00384 }
00385 
00386 void OoUtils::importTextPosition( const QString& text_position, QString& value, QString& relativetextsize )
00387 {
00388     //OO: <vertical position (% or sub or super)> [<size as %>]
00389     //Examples: "super" or "super 58%" or "82% 58%" (where 82% is the vertical position)
00390     // TODO in kword: vertical positions other than sub/super
00391     QStringList lst = QStringList::split( ' ', text_position );
00392     if ( !lst.isEmpty() )
00393     {
00394         QString textPos = lst.front().stripWhiteSpace();
00395         QString textSize;
00396         lst.pop_front();
00397         if ( !lst.isEmpty() )
00398             textSize = lst.front().stripWhiteSpace();
00399         if ( !lst.isEmpty() )
00400             kdWarning(30519) << "Strange text position: " << text_position << endl;
00401         bool super = textPos == "super";
00402         bool sub = textPos == "sub";
00403         if ( textPos.endsWith("%") )
00404         {
00405             textPos.truncate( textPos.length() - 1 );
00406             // This is where we interpret the text position into kotext's simpler
00407             // "super" or "sub".
00408             double val = textPos.toDouble();
00409             if ( val > 0 )
00410                 super = true;
00411             else if ( val < 0 )
00412                 sub = true;
00413         }
00414         if ( super )
00415             value = "2";
00416         else if ( sub )
00417             value = "1";
00418         else
00419             value = "0";
00420         if ( !textSize.isEmpty() && textSize.endsWith("%") )
00421         {
00422             textSize.truncate( textSize.length() - 1 );
00423             double textSizeValue = textSize.toDouble() / 100; // e.g. 0.58
00424             relativetextsize = QString::number( textSizeValue );
00425         }
00426     }
00427     else
00428         value = "0";
00429 }
00430 
00431 void OoUtils::createDocumentInfo(QDomDocument &_meta, QDomDocument & docinfo)
00432 {
00433     QDomNode meta   = KoDom::namedItemNS( _meta, ooNS::office, "document-meta" );
00434     QDomNode office = KoDom::namedItemNS( meta, ooNS::office, "meta" );
00435 
00436     if ( office.isNull() )
00437         return;
00438     QDomElement elementDocInfo  = docinfo.documentElement();
00439 
00440     QDomElement e = KoDom::namedItemNS( office, ooNS::dc, "creator" );
00441     if ( !e.isNull() && !e.text().isEmpty() )
00442     {
00443         QDomElement author = docinfo.createElement( "author" );
00444         QDomElement t = docinfo.createElement( "full-name" );
00445         author.appendChild( t );
00446         t.appendChild( docinfo.createTextNode( e.text() ) );
00447         elementDocInfo.appendChild( author);
00448     }
00449 
00450     e = KoDom::namedItemNS( office, ooNS::dc, "title" );
00451     if ( !e.isNull() && !e.text().isEmpty() )
00452     {
00453         QDomElement about = docinfo.createElement( "about" );
00454         QDomElement title = docinfo.createElement( "title" );
00455         about.appendChild( title );
00456         title.appendChild( docinfo.createTextNode( e.text() ) );
00457         elementDocInfo.appendChild( about );
00458     }
00459 
00460     e = KoDom::namedItemNS( office, ooNS::dc, "description" );
00461     if ( !e.isNull() && !e.text().isEmpty() )
00462     {
00463         QDomElement about = elementDocInfo.namedItem( "about" ).toElement();
00464         if ( about.isNull() ) {
00465             about = docinfo.createElement( "about" );
00466             elementDocInfo.appendChild( about );
00467         }
00468         QDomElement title = docinfo.createElement( "abstract" );
00469         about.appendChild( title );
00470         title.appendChild( docinfo.createTextNode( e.text() ) );
00471     }
00472     e = KoDom::namedItemNS( office, ooNS::dc, "subject" );
00473     if ( !e.isNull() && !e.text().isEmpty() )
00474     {
00475         QDomElement about = elementDocInfo.namedItem( "about" ).toElement();
00476         if ( about.isNull() ) {
00477             about = docinfo.createElement( "about" );
00478             elementDocInfo.appendChild( about );
00479         }
00480         QDomElement subject = docinfo.createElement( "subject" );
00481         about.appendChild( subject );
00482         subject.appendChild( docinfo.createTextNode( e.text() ) );
00483     }
00484     e = KoDom::namedItemNS( office, ooNS::meta, "keywords" );
00485     if ( !e.isNull() )
00486     {
00487         QDomElement about = elementDocInfo.namedItem( "about" ).toElement();
00488         if ( about.isNull() ) {
00489             about = docinfo.createElement( "about" );
00490             elementDocInfo.appendChild( about );
00491         }
00492         QDomElement tmp = KoDom::namedItemNS( e, ooNS::meta, "keyword" );
00493         if ( !tmp.isNull() && !tmp.text().isEmpty() )
00494         {
00495             QDomElement keyword = docinfo.createElement( "keyword" );
00496             about.appendChild( keyword );
00497             keyword.appendChild( docinfo.createTextNode( tmp.text() ) );
00498         }
00499     }
00500 }
00501 
00502 KoFilter::ConversionStatus OoUtils::loadAndParse(const QString& fileName, QDomDocument& doc, KoStore *m_store )
00503 {
00504     kdDebug(30518) << "loadAndParse: Trying to open " << fileName << endl;
00505 
00506     if (!m_store->open(fileName))
00507     {
00508         kdWarning(30519) << "Entry " << fileName << " not found!" << endl;
00509         return KoFilter::FileNotFound;
00510     }
00511     KoFilter::ConversionStatus convertStatus = loadAndParse( m_store->device(),doc, fileName );
00512     m_store->close();
00513     return convertStatus;
00514 
00515 }
00516 
00517 KoFilter::ConversionStatus OoUtils::loadAndParse(QIODevice* io, QDomDocument& doc, const QString & fileName)
00518 {
00519     QXmlInputSource source( io );
00520     // Copied from QDomDocumentPrivate::setContent, to change the whitespace thing
00521     QXmlSimpleReader reader;
00522     KoDocument::setupXmlReader( reader, true /*namespaceProcessing*/ );
00523 
00524     // Error variables for QDomDocument::setContent
00525     QString errorMsg;
00526     int errorLine, errorColumn;
00527     if ( !doc.setContent( &source, &reader, &errorMsg, &errorLine, &errorColumn ) )
00528     {
00529         kdError(30519) << "Parsing error in " << fileName << "! Aborting!" << endl
00530             << " In line: " << errorLine << ", column: " << errorColumn << endl
00531             << " Error message: " << errorMsg << endl;
00532         return KoFilter::ParsingError;
00533     }
00534 
00535     kdDebug(30519) << "File " << fileName << " loaded and parsed!" << endl;
00536 
00537     return KoFilter::OK;
00538 
00539 }
00540 
00541 KoFilter::ConversionStatus OoUtils::loadAndParse(const QString& filename, QDomDocument& doc, KZip * m_zip)
00542 {
00543     kdDebug(30519) << "Trying to open " << filename << endl;
00544 
00545     if (!m_zip)
00546     {
00547         kdError(30519) << "No ZIP file!" << endl;
00548         return KoFilter::CreationError; // Should not happen
00549     }
00550 
00551     const KArchiveEntry* entry = m_zip->directory()->entry( filename );
00552     if (!entry)
00553     {
00554         kdWarning(30519) << "Entry " << filename << " not found!" << endl;
00555         return KoFilter::FileNotFound;
00556     }
00557     if (entry->isDirectory())
00558     {
00559         kdWarning(30519) << "Entry " << filename << " is a directory!" << endl;
00560         return KoFilter::WrongFormat;
00561     }
00562     const KZipFileEntry* f = static_cast<const KZipFileEntry *>(entry);
00563     kdDebug(30519) << "Entry " << filename << " has size " << f->size() << endl;
00564     QIODevice* io = f->device();
00565     KoFilter::ConversionStatus convertStatus = loadAndParse( io,doc, filename );
00566     delete io;
00567     return convertStatus;
00568 }
00569 
00570 KoFilter::ConversionStatus OoUtils::loadThumbnail( QImage& thumbnail, KZip * m_zip )
00571 {
00572     const QString filename( "Thumbnails/thumbnail.png" );
00573     kdDebug(30519) << "Trying to open thumbnail " << filename << endl;
00574 
00575     if (!m_zip)
00576     {
00577         kdError(30519) << "No ZIP file!" << endl;
00578         return KoFilter::CreationError; // Should not happen
00579     }
00580 
00581     const KArchiveEntry* entry = m_zip->directory()->entry( filename );
00582     if (!entry)
00583     {
00584         kdWarning(30519) << "Entry " << filename << " not found!" << endl;
00585         return KoFilter::FileNotFound;
00586     }
00587     if (entry->isDirectory())
00588     {
00589         kdWarning(30519) << "Entry " << filename << " is a directory!" << endl;
00590         return KoFilter::WrongFormat;
00591     }
00592     const KZipFileEntry* f = static_cast<const KZipFileEntry *>(entry);
00593     QIODevice* io=f->device();
00594     kdDebug(30519) << "Entry " << filename << " has size " << f->size() << endl;
00595 
00596     if ( ! io->open( IO_ReadOnly ) )
00597     {
00598         kdWarning(30519) << "Thumbnail could not be opened!" <<endl;
00599         delete io;
00600         return KoFilter::StupidError;
00601     }
00602 
00603     QImageIO imageIO( io, "PNG" );
00604     if ( ! imageIO.read() )
00605     {
00606         kdWarning(30519) << "Thumbnail could not be read!" <<endl;
00607         delete io;
00608         return KoFilter::StupidError;
00609     }
00610 
00611     io->close();
00612 
00613     thumbnail = imageIO.image();
00614 
00615     if ( thumbnail.isNull() )
00616     {
00617         kdWarning(30519) << "Read thumbnail is null!" <<endl;
00618         delete io;
00619         return KoFilter::StupidError;
00620     }
00621 
00622     delete io;
00623 
00624     kdDebug(30519) << "File " << filename << " loaded!" << endl;
00625 
00626     return KoFilter::OK;
00627 }
KDE Home | KDE Accessibility Home | Description of Access Keys