00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <float.h>
00022 #include <math.h>
00023
00024 #include <qcolor.h>
00025 #include <qfile.h>
00026 #include <qfont.h>
00027 #include <qpen.h>
00028 #include <qxml.h>
00029
00030 #include "opencalcimport.h"
00031
00032 #include <kdebug.h>
00033 #include <KoDocumentInfo.h>
00034 #include <kgenericfactory.h>
00035 #include <kmessagebox.h>
00036 #include <kmdcodec.h>
00037 #include <KoFilterChain.h>
00038 #include <KoGlobal.h>
00039 #include <KoUnit.h>
00040 #include <KoStyleStack.h>
00041 #include <KoDom.h>
00042 #include <ooutils.h>
00043
00044 #include <kspread_cell.h>
00045 #include <kspread_condition.h>
00046 #include <kspread_doc.h>
00047 #include <kspread_global.h>
00048 #include <kspread_map.h>
00049 #include <kspread_sheet.h>
00050 #include <kspread_sheetprint.h>
00051 #include <kspread_style.h>
00052 #include <kspread_style_manager.h>
00053 #include <kspread_util.h>
00054 #include <kspread_value.h>
00055
00056 #define SECSPERDAY (24 * 60 * 60)
00057
00058 using namespace KSpread;
00059
00060 class OpenCalcImportFactory : KGenericFactory<OpenCalcImport, KoFilter>
00061 {
00062 public:
00063 OpenCalcImportFactory(void) : KGenericFactory<OpenCalcImport, KoFilter> ("kspreadopencalcimport")
00064 {}
00065 protected:
00066 virtual void setupTranslations( void )
00067 {
00068 KGlobal::locale()->insertCatalogue( "kofficefilters" );
00069 }
00070 };
00071
00072 K_EXPORT_COMPONENT_FACTORY( libopencalcimport, OpenCalcImportFactory() )
00073
00074 OpenCalcImport::OpenCalcPoint::OpenCalcPoint( QString const & str )
00075 : isRange( false )
00076 {
00077 bool inQuote = false;
00078
00079 int l = str.length();
00080 int colonPos = -1;
00081 QString range;
00082
00083
00084 for ( int i = 0; i < l; ++i )
00085 {
00086 if ( str[i] == '$' )
00087 continue;
00088 if ( str[i] == '\'' )
00089 {
00090 inQuote = !inQuote;
00091 }
00092 else if ( str[i] == '.' )
00093 {
00094 if ( !inQuote )
00095 {
00096 if ( i != 0 && i != (colonPos + 1) )
00097 range += '!';
00098 }
00099 else
00100 range += '.';
00101 }
00102 else if ( str[i] == ':' )
00103 {
00104 if ( !inQuote )
00105 {
00106 isRange = true;
00107 colonPos = i;
00108 }
00109 range += ':';
00110 }
00111 else
00112 range += str[i];
00113 }
00114
00115 translation = range;
00116
00117 if ( isRange )
00118 {
00119 KSpread::Range newRange( range );
00120 table = newRange.sheetName();
00121 topLeft = newRange.range().topLeft();
00122 botRight = newRange.range().bottomRight();
00123 }
00124 else
00125 {
00126 Point newPoint( range );
00127 table = newPoint.sheetName();
00128 topLeft = newPoint.pos();
00129 botRight = newPoint.pos();
00130 }
00131 }
00132
00133
00134 OpenCalcImport::OpenCalcImport( KoFilter *, const char *, const QStringList & )
00135 : KoFilter(),
00136 m_styles( 17, true ),
00137 m_defaultStyles( 17, true ),
00138 m_formats( 17, true )
00139 {
00140 m_styles.setAutoDelete( true );
00141 m_defaultStyles.setAutoDelete( true );
00142 m_formats.setAutoDelete( true );
00143 }
00144
00145 OpenCalcImport::~OpenCalcImport()
00146 {
00147 }
00148
00149 double timeToNum( int h, int m, int s )
00150 {
00151 int secs = h * 3600 + m * 60 + s;
00152 return (double) secs / (double) SECSPERDAY;
00153 }
00154
00155 bool OpenCalcImport::readRowFormat( QDomElement & rowNode, QDomElement * rowStyle,
00156 Sheet * table, int & row, int & number,
00157 bool isLast )
00158 {
00159 if ( rowNode.isNull() )
00160 return false;
00161
00162 QDomNode node;
00163 if ( rowStyle )
00164 {
00165 node = rowStyle->firstChild();
00166 kdDebug(30518) << "RowStyle: " << rowStyle << ", " << rowStyle->tagName() << endl;
00167 }
00168
00169 double height = -1.0;
00170 bool insertPageBreak = false;
00171 Format layout( table, table->doc()->styleManager()->defaultStyle() );
00172
00173 while( !node.isNull() )
00174 {
00175 QDomElement property = node.toElement();
00176
00177 kdDebug(30518) << "Row: Child exists: " << property.tagName() << endl;
00178 if ( !property.isNull() && property.localName() == "properties" && property.namespaceURI() == ooNS::style )
00179 {
00180 if ( property.hasAttributeNS( ooNS::style, "row-height" ) )
00181 {
00182 height = KoUnit::parseValue( property.attributeNS( ooNS::style, "row-height", QString::null ) , -1 );
00183 }
00184
00185 if ( property.hasAttributeNS( ooNS::fo, "break-before" ) )
00186 {
00187 if ( property.attributeNS( ooNS::fo, "break-before", QString::null ) == "page" )
00188 {
00189 insertPageBreak = true;
00190 }
00191 }
00192
00193 loadStyleProperties( &layout, property );
00194 }
00195
00196 node = node.nextSibling();
00197 }
00198
00199 if ( rowNode.hasAttributeNS( ooNS::table, "number-rows-repeated" ) )
00200 {
00201 bool ok = true;
00202 int n = rowNode.attributeNS( ooNS::table, "number-rows-repeated", QString::null ).toInt( &ok );
00203 if ( ok )
00204 number = n;
00205 kdDebug(30518) << "Row repeated: " << number << endl;
00206 }
00207
00208 if ( isLast )
00209 {
00210 if ( number > 30 )
00211 number = 30;
00212 }
00213 else
00214 {
00215 if ( number > 256 )
00216 number = 256;
00217 }
00218
00219 for ( int i = 0; i < number; ++i )
00220 {
00221 RowFormat * rowL = table->nonDefaultRowFormat( row );
00222 rowL->copy( layout );
00223
00224 if ( height != -1 )
00225 {
00226 kdDebug(30518) << "Setting row height to " << height << endl;
00227 rowL->setHeight( int( height ) );
00228 }
00229
00230
00231
00232
00233
00234 ++row;
00235 }
00236
00237 return true;
00238 }
00239
00240 QString OpenCalcImport::translatePar( QString & par ) const
00241 {
00242 OpenCalcPoint point( par );
00243 kdDebug(30518) << " Parameter: " << par << ", Translation: " << point.translation << endl;
00244
00245 return point.translation;
00246 }
00247
00248 void OpenCalcImport::checkForNamedAreas( QString & formula ) const
00249 {
00250 int l = formula.length();
00251 int i = 0;
00252 QString word;
00253 int start = 0;
00254 while ( i < l )
00255 {
00256 if ( formula[i].isLetterOrNumber() )
00257 {
00258 word += formula[i];
00259 ++i;
00260 continue;
00261 }
00262 if ( word.length() > 0 )
00263 {
00264 if ( m_namedAreas.find( word ) != m_namedAreas.end() )
00265 {
00266 formula = formula.replace( start, word.length(), "'" + word + "'" );
00267 l = formula.length();
00268 ++i;
00269 kdDebug(30518) << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
00270 }
00271 }
00272
00273 ++i;
00274 word = "";
00275 start = i;
00276 }
00277 if ( word.length() > 0 )
00278 {
00279 if ( m_namedAreas.find( word ) != m_namedAreas.end() )
00280 {
00281 formula = formula.replace( start, word.length(), "'" + word + "'" );
00282 l = formula.length();
00283 ++i;
00284 kdDebug(30518) << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
00285 }
00286 }
00287 }
00288
00289 void OpenCalcImport::convertFormula( QString & text, QString const & f ) const
00290 {
00291 kdDebug(30518) << "Parsing formula: " << f << endl;
00292
00293 QString formula;
00294 QString parameter;
00295
00296 int l = f.length();
00297 int p = 0;
00298
00299 while ( p < l )
00300 {
00301 if ( f[p] == '(' || f[p] == '[' )
00302 {
00303 break;
00304 }
00305
00306 formula += f[p];
00307 ++p;
00308 }
00309
00310 if ( parameter.isEmpty() )
00311 {
00312 checkForNamedAreas( formula );
00313 }
00314
00315 kdDebug(30518) << "Formula: " << formula << ", Parameter: " << parameter << ", P: " << p << endl;
00316
00317
00318
00319 if ( formula == "=MULTIPLE.OPERATIONS" )
00320 formula = "=MULTIPLEOPERATIONS";
00321
00322 QString par;
00323 bool isPar = false;
00324 bool inQuote = false;
00325
00326 while ( p < l )
00327 {
00328 if ( f[p] == '"' )
00329 {
00330 inQuote = !inQuote;
00331 parameter += '"';
00332 }
00333 else if ( f[p] == '[' )
00334 {
00335 if ( !inQuote )
00336 isPar = true;
00337 else
00338 parameter += '[';
00339 }
00340 else if ( f[p] == ']' )
00341 {
00342 if ( inQuote )
00343 {
00344 parameter += ']';
00345 continue;
00346 }
00347
00348 isPar = false;
00349 parameter += translatePar( par );
00350 par = "";
00351 }
00352 else if ( isPar )
00353 {
00354 par += f[p];
00355 }
00356 else if ( f[p] == '=' )
00357 {
00358 if ( inQuote )
00359 parameter += '=';
00360 else
00361 parameter += "==";
00362 }
00363 else if ( f[p] == ')' )
00364 {
00365 if ( !inQuote )
00366 parameter += ")";
00367 }
00368 else
00369 parameter += f[p];
00370
00371 ++p;
00372 if ( p == l )
00373 checkForNamedAreas( parameter );
00374 }
00375
00376 text = formula + parameter;
00377 kdDebug(30518) << "New formula: " << text << endl;
00378 }
00379
00380 bool OpenCalcImport::readCells( QDomElement & rowNode, Sheet * table, int row, int & columns )
00381 {
00382 bool ok = true;
00383 int spanC = 1;
00384 int spanR = 1;
00385
00386
00387 QDomNode cellNode = KoDom::namedItemNS( rowNode, ooNS::table, "table-cell" );
00388
00389 while ( !cellNode.isNull() )
00390 {
00391 spanR = 1; spanC = 1;
00392
00393 QDomElement e = cellNode.toElement();
00394 if ( e.isNull() )
00395 {
00396 ++columns;
00397
00398 cellNode = cellNode.nextSibling();
00399 continue;
00400 }
00401
00402 Cell* cell = 0;
00403
00404 kdDebug(30518) << " Cell: " << columns << ", " << row << endl;
00405
00406
00407 if ( e.hasAttributeNS( ooNS::table, "number-columns-spanned" ) )
00408 {
00409 int span = e.attributeNS( ooNS::table, "number-columns-spanned", QString::null ).toInt( &ok );
00410 if ( ok )
00411 spanC = span;
00412 }
00413 if ( e.hasAttributeNS( ooNS::table, "number-rows-spanned" ) )
00414 {
00415 int span = e.attributeNS( ooNS::table, "number-rows-spanned", QString::null ).toInt( &ok );
00416 if ( ok )
00417 spanR = span;
00418 }
00419
00420 QString text;
00421 QDomElement textP = KoDom::namedItemNS( e, ooNS::text, "p" );
00422 if ( !textP.isNull() )
00423 {
00424 QDomElement subText = textP.firstChild().toElement();
00425 if ( !subText.isNull() )
00426 {
00427
00428 text = subText.text();
00429
00430 if ( subText.hasAttributeNS( ooNS::xlink, "href" ) )
00431 {
00432 QString link = subText.attributeNS( ooNS::xlink, "href", QString::null );
00433 if ( link[0]=='#' )
00434 link=link.remove( 0, 1 );
00435 if ( !cell )
00436 cell = table->nonDefaultCell( columns, row );
00437 cell->setLink( link );
00438 }
00439 }
00440 else
00441 text = textP.text();
00442 }
00443 QDomElement annotation = KoDom::namedItemNS( e, ooNS::office, "annotation" );
00444 if ( !annotation.isNull() )
00445 {
00446 QString comment;
00447 QDomNode node = annotation.firstChild();
00448 while( !node.isNull() )
00449 {
00450 QDomElement commentElement = node.toElement();
00451 if( !commentElement.isNull() )
00452 if ( commentElement.localName() == "p" && e.namespaceURI()==ooNS::text)
00453 {
00454 if( !comment.isEmpty() ) comment.append( '\n' );
00455 comment.append( commentElement.text() );
00456 }
00457
00458 node = node.nextSibling();
00459 }
00460
00461 if( !comment.isEmpty() )
00462 {
00463 if ( !cell )
00464 cell = table->nonDefaultCell( columns, row );
00465 kdDebug(30518)<<" columns :"<<columns<<" row :"<<row<<endl;
00466 cell->format()->setComment( comment );
00467 }
00468 }
00469
00470 kdDebug(30518) << "Contains: " << text << endl;
00471 bool isFormula = false;
00472
00473 if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
00474 {
00475 if ( !cell )
00476 cell = table->nonDefaultCell( columns, row );
00477
00478 QString psName( "Default" );
00479 if ( e.hasAttributeNS( ooNS::style, "parent-style-name" ) )
00480 psName = e.attributeNS( ooNS::style, "parent-style-name", QString::null );
00481
00482 kdDebug(30518) << "Default style: " << psName << endl;
00483 Format * layout = m_defaultStyles[psName];
00484
00485 if ( layout )
00486 cell->format()->copy( *layout );
00487
00488 QDomElement * st = 0;
00489 if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
00490 {
00491 kdDebug(30518) << "Style: " << e.attributeNS( ooNS::table, "style-name", QString::null ) << endl;
00492 st = m_styles[ e.attributeNS( ooNS::table, "style-name", QString::null ) ];
00493 }
00494 if ( st )
00495 {
00496 kdDebug(30518) << "Style: adapting " << endl;
00497 QDomNode node = st->firstChild();
00498 bool foundValidation = false;
00499 while( !node.isNull() )
00500 {
00501 QDomElement property = node.toElement();
00502 if ( !property.isNull() )
00503 {
00504 kdDebug(30518)<<"property.tagName() :"<<property.tagName()<<endl;
00505 if ( property.localName()=="map" && property.namespaceURI() == ooNS::style && !foundValidation)
00506 {
00507 loadCondition( cell, property );
00508 foundValidation = true;
00509 }
00510 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
00511 {
00512 loadStyleProperties( cell->format(), property );
00513 if ( cell->format()->getAngle( columns, row ) != 0 )
00514 {
00515 QFontMetrics fm( cell->format()->textFont( columns, row ) );
00516 int tmpAngle = cell->format()->getAngle( columns, row );
00517 int textHeight = static_cast<int>( cos( tmpAngle * M_PI / 180 )
00518 * ( fm.ascent() + fm.descent() )
00519 + abs ( ( int )( fm.width( cell->strOutText() )
00520 * sin( tmpAngle * M_PI / 180 ) ) ) );
00521
00522
00523
00524
00525
00526
00527 kdDebug(30518) << "Rotation: height: " << textHeight << endl;
00528
00529 RowFormat * l = table->rowFormat( row );
00530 if ( l->height() < textHeight )
00531 {
00532 if ( l->isDefault() )
00533 l = table->nonDefaultRowFormat( row );
00534
00535 l->setHeight( textHeight + 2 );
00536 }
00537 }
00538 }
00539 }
00540 node = node.nextSibling();
00541 }
00542 }
00543 }
00544 else
00545 {
00546 if ( !cell )
00547 cell = table->nonDefaultCell( columns, row );
00548
00549 QString psName( "Default" );
00550 kdDebug(30518) << "Default style: " << psName << endl;
00551 Format * layout = m_defaultStyles[psName];
00552
00553 if ( layout )
00554 cell->format()->copy( *layout );
00555 }
00556 if ( e.hasAttributeNS( ooNS::table, "formula" ) )
00557 {
00558 isFormula = true;
00559 QString formula;
00560 convertFormula( formula, e.attributeNS( ooNS::table, "formula", QString::null ) );
00561
00562 if ( !cell )
00563 cell = table->nonDefaultCell( columns, row );
00564 cell->setCellText( formula );
00565 }
00566 if ( e.hasAttributeNS( ooNS::table, "validation-name" ) )
00567 {
00568 kdDebug(30518)<<" Celle has a validation :"<<e.attributeNS( ooNS::table, "validation-name", QString::null )<<endl;
00569 loadOasisValidation( cell->getValidity(), e.attributeNS( ooNS::table, "validation-name", QString::null ) );
00570 }
00571 if ( e.hasAttributeNS( ooNS::table, "value-type" ) )
00572 {
00573 if ( !cell )
00574 cell = table->nonDefaultCell( columns, row );
00575
00576 cell->setCellText( text );
00577
00578 QString value = e.attributeNS( ooNS::table, "value", QString::null );
00579 QString type = e.attributeNS( ooNS::table, "value-type", QString::null );
00580
00581 kdDebug(30518) << "Value: " << value << ", type: " << type << endl;
00582
00583 bool ok = false;
00584 double dv = 0.0;
00585
00586 if ( ( type == "float" ) || ( type == "currency" ) )
00587 {
00588 dv = value.toDouble( &ok );
00589 if ( ok )
00590 {
00591 if ( !isFormula )
00592 cell->setValue( dv );
00593
00594 if ( type == "currency" )
00595 {
00596 cell->format()->setCurrency( 1, e.attributeNS( ooNS::table, "currency", QString::null ) );
00597 cell->format()->setFormatType( Money_format );
00598 }
00599 }
00600 }
00601 else
00602 if ( type == "percentage" )
00603 {
00604 dv = value.toDouble( &ok );
00605 if ( ok )
00606 {
00607 if ( !isFormula )
00608 cell->setValue( dv );
00609
00610
00611
00612 cell->format()->setFormatType( Percentage_format );
00613 }
00614 }
00615 else if ( type == "boolean" )
00616 {
00617 if ( value.isEmpty() )
00618 value = e.attributeNS( ooNS::table, "boolean-value", QString::null );
00619
00620 kdDebug(30518) << "Type: boolean" << endl;
00621 if ( value == "true" )
00622 cell->setValue( true );
00623 else
00624 cell->setValue( false );
00625 ok = true;
00626 cell->format()->setFormatType( Custom_format );
00627 }
00628 else if ( type == "date" )
00629 {
00630 if ( value.isEmpty() )
00631 value = e.attributeNS( ooNS::table, "date-value", QString::null );
00632 kdDebug(30518) << "Type: date, value: " << value << endl;
00633
00634
00635 int year=0, month=0, day=0;
00636 ok = false;
00637
00638 int p1 = value.find( '-' );
00639 if ( p1 > 0 )
00640 year = value.left( p1 ).toInt( &ok );
00641
00642 kdDebug(30518) << "year: " << value.left( p1 ) << endl;
00643
00644 int p2 = value.find( '-', ++p1 );
00645
00646 if ( ok )
00647 month = value.mid( p1, p2 - p1 ).toInt( &ok );
00648
00649 kdDebug(30518) << "month: " << value.mid( p1, p2 - p1 ) << endl;
00650
00651 if ( ok )
00652 day = value.right( value.length() - p2 - 1 ).toInt( &ok );
00653
00654 kdDebug(30518) << "day: " << value.right( value.length() - p2 ) << endl;
00655
00656 if ( ok )
00657 {
00658 QDateTime dt( QDate( year, month, day ) );
00659
00660
00661 cell->setValue( QDate( year, month, day ) );
00662 kdDebug(30518) << "Set QDate: " << year << " - " << month << " - " << day << endl;
00663 }
00664 }
00665 else if ( type == "time" )
00666 {
00667 if ( value.isEmpty() )
00668 value = e.attributeNS( ooNS::table, "time-value", QString::null );
00669
00670 kdDebug(30518) << "Type: time: " << value << endl;
00671
00672 int hours=0, minutes=0, seconds=0;
00673 int l = value.length();
00674 QString num;
00675
00676 for ( int i = 0; i < l; ++i )
00677 {
00678 if ( value[i].isNumber() )
00679 {
00680 num += value[i];
00681 continue;
00682 }
00683 else if ( value[i] == 'H' )
00684 hours = num.toInt( &ok );
00685 else if ( value[i] == 'M' )
00686 minutes = num.toInt( &ok );
00687 else if ( value[i] == 'S' )
00688 seconds = num.toInt( &ok );
00689 else
00690 continue;
00691
00692 kdDebug(30518) << "Num: " << num << endl;
00693
00694 num = "";
00695 if ( !ok )
00696 break;
00697 }
00698
00699 kdDebug(30518) << "Hours: " << hours << ", " << minutes << ", " << seconds << endl;
00700
00701 if ( ok )
00702 {
00703
00704
00705 cell->setValue( QTime( hours % 24, minutes, seconds ) );
00706 cell->format()->setFormatType( Custom_format );
00707 }
00708 }
00709
00710
00711 if ( !ok )
00712 cell->setCellText( text );
00713 }
00714 else if ( !text.isEmpty() )
00715 {
00716 if ( !cell )
00717 cell = table->nonDefaultCell( columns, row );
00718 cell->setCellText( text );
00719 }
00720
00721 if ( spanR > 1 || spanC > 1 )
00722 {
00723 if ( !cell )
00724 cell = table->nonDefaultCell( columns, row );
00725 cell->mergeCells( columns, row, spanC - 1, spanR - 1 );
00726 }
00727
00728 cellNode = cellNode.nextSibling();
00729
00730 if ( e.hasAttributeNS( ooNS::table, "number-columns-repeated" ) )
00731 {
00732
00733 bool ok = false;
00734 int number = e.attributeNS( ooNS::table, "number-columns-repeated", QString::null ).toInt( &ok );
00735 Cell* cellDest = 0;
00736
00737
00738 if ( !ok || cellNode.isNull() )
00739 {
00740 if ( number > 10 )
00741 number = 10;
00742 }
00743
00744 for ( int i = 1; i < number; ++i )
00745 {
00746 ++columns;
00747
00748 if ( cell )
00749 {
00750 cellDest = table->nonDefaultCell( columns, row );
00751 cellDest->copyAll( cell );
00752 }
00753 }
00754 }
00755
00756 ++columns;
00757 }
00758
00759 return true;
00760 }
00761
00762
00763 void OpenCalcImport::loadCondition( Cell*cell,const QDomElement &property )
00764 {
00765 kdDebug(30518)<<"void OpenCalcImport::loadCondition( Cell*cell,const QDomElement &property )*******\n";
00766 loadOasisCondition( cell, property );
00767 }
00768
00769 void OpenCalcImport::loadOasisCondition(Cell*cell,const QDomElement &property )
00770 {
00771 QDomElement elementItem( property );
00772 StyleManager * manager = cell->sheet()->doc()->styleManager();
00773
00774 QValueList<Conditional> cond;
00775 while ( !elementItem.isNull() )
00776 {
00777 kdDebug(30518)<<"elementItem.tagName() :"<<elementItem.tagName()<<endl;
00778
00779 if ( elementItem.localName()== "map" && property.namespaceURI() == ooNS::style )
00780 {
00781 bool ok = true;
00782 kdDebug(30518)<<"elementItem.attribute(style:condition ) :"<<elementItem.attributeNS( ooNS::style, "condition", QString::null )<<endl;
00783 Conditional newCondition;
00784 loadOasisConditionValue( elementItem.attributeNS( ooNS::style, "condition", QString::null ), newCondition );
00785 if ( elementItem.hasAttributeNS( ooNS::style, "apply-style-name" ) )
00786 {
00787 kdDebug(30518)<<"elementItem.attribute( style:apply-style-name ) :"<<elementItem.attributeNS( ooNS::style, "apply-style-name", QString::null )<<endl;
00788 newCondition.styleName = new QString( elementItem.attributeNS( ooNS::style, "apply-style-name", QString::null ) );
00789 newCondition.style = manager->style( *newCondition.styleName );
00790 if ( !newCondition.style )
00791 ok = false;
00792 else
00793 ok = true;
00794 }
00795
00796 if ( ok )
00797 cond.append( newCondition );
00798 else
00799 kdDebug(30518) << "Error loading condition " << elementItem.nodeName()<< endl;
00800 }
00801 elementItem = elementItem.nextSibling().toElement();
00802 }
00803 if ( !cond.isEmpty() )
00804 cell->setConditionList( cond );
00805 }
00806
00807 void OpenCalcImport::loadOasisConditionValue( const QString &styleCondition, Conditional &newCondition )
00808 {
00809 QString val( styleCondition );
00810 if ( val.contains( "cell-content()" ) )
00811 {
00812 val = val.remove( "cell-content()" );
00813 loadOasisCondition( val,newCondition );
00814 }
00815
00816
00817 if ( val.contains( "cell-content-is-between(" ) )
00818 {
00819 val = val.remove( "cell-content-is-between(" );
00820 val = val.remove( ")" );
00821 QStringList listVal = QStringList::split( "," , val );
00822 loadOasisValidationValue( listVal, newCondition );
00823 newCondition.cond = Conditional::Between;
00824 }
00825 if ( val.contains( "cell-content-is-not-between(" ) )
00826 {
00827 val = val.remove( "cell-content-is-not-between(" );
00828 val = val.remove( ")" );
00829 QStringList listVal = QStringList::split( ",", val );
00830 loadOasisValidationValue( listVal,newCondition );
00831 newCondition.cond = Conditional::Different;
00832 }
00833
00834 }
00835
00836
00837 void OpenCalcImport::loadOasisCondition( QString &valExpression, Conditional &newCondition )
00838 {
00839 QString value;
00840 if (valExpression.find( "<=" )==0 )
00841 {
00842 value = valExpression.remove( 0,2 );
00843 newCondition.cond = Conditional::InferiorEqual;
00844 }
00845 else if (valExpression.find( ">=" )==0 )
00846 {
00847 value = valExpression.remove( 0,2 );
00848 newCondition.cond = Conditional::SuperiorEqual;
00849 }
00850 else if (valExpression.find( "!=" )==0 )
00851 {
00852
00853 value = valExpression.remove( 0,2 );
00854 newCondition.cond = Conditional::DifferentTo;
00855 }
00856 else if ( valExpression.find( "<" )==0 )
00857 {
00858 value = valExpression.remove( 0,1 );
00859 newCondition.cond = Conditional::Inferior;
00860 }
00861 else if(valExpression.find( ">" )==0 )
00862 {
00863 value = valExpression.remove( 0,1 );
00864 newCondition.cond = Conditional::Superior;
00865 }
00866 else if (valExpression.find( "=" )==0 )
00867 {
00868 value = valExpression.remove( 0,1 );
00869 newCondition.cond = Conditional::Equal;
00870 }
00871 else
00872 kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
00873 kdDebug(30518)<<" value :"<<value<<endl;
00874 bool ok = false;
00875 newCondition.val1 = value.toDouble(&ok);
00876 if ( !ok )
00877 {
00878 newCondition.val1 = value.toInt(&ok);
00879 if ( !ok )
00880 {
00881 newCondition.strVal1 = new QString( value );
00882 kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
00883 }
00884
00885 }
00886 }
00887
00888
00889 void OpenCalcImport::loadOasisValidationValue( const QStringList &listVal, Conditional &newCondition )
00890 {
00891 bool ok = false;
00892 kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
00893
00894 newCondition.val1 = listVal[0].toDouble(&ok);
00895 if ( !ok )
00896 {
00897 newCondition.val1 = listVal[0].toInt(&ok);
00898 if ( !ok )
00899 {
00900 newCondition.strVal1 = new QString( listVal[0] );
00901 kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
00902 }
00903 }
00904 ok=false;
00905 newCondition.val2 = listVal[1].toDouble(&ok);
00906 if ( !ok )
00907 {
00908 newCondition.val2 = listVal[1].toInt(&ok);
00909 if ( !ok )
00910 {
00911 newCondition.strVal2 = new QString( listVal[1] );
00912 kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
00913 }
00914 }
00915 }
00916
00917
00918 bool OpenCalcImport::readRowsAndCells( QDomElement & content, Sheet * table )
00919 {
00920 kdDebug(30518) << endl << "Reading in rows " << endl;
00921
00922 int i = 1;
00923 int row = 1;
00924 int columns = 1;
00925 int backupRow = 1;
00926 QDomElement * rowStyle = 0;
00927
00928
00929
00930 QDomNode rowNode = KoDom::namedItemNS( content, ooNS::table, "table-row" );
00931
00932 while ( !rowNode.isNull() )
00933 {
00934 bool collapsed = false;
00935
00936 int number = 1;
00937 QDomElement r = rowNode.toElement();
00938
00939 if ( r.isNull() )
00940 return false;
00941
00942 if ( r.hasAttributeNS( ooNS::table, "style-name" ) )
00943 {
00944 QString style = r.attributeNS( ooNS::table, "style-name", QString::null );
00945 rowStyle = m_styles[ style ];
00946 kdDebug(30518) << "Row style: " << style << endl;
00947 }
00948
00949 collapsed = ( r.attributeNS( ooNS::table, "visibility", QString::null ) == "collapse" );
00950
00951 backupRow = row;
00952
00953 rowNode = rowNode.nextSibling();
00954
00955 if ( !readRowFormat( r, rowStyle, table, row, number, rowNode.isNull() ) )
00956 return false;
00957
00958 if ( !readCells( r, table, backupRow, columns ) )
00959 return false;
00960
00961 RowFormat * srcLayout = table->nonDefaultRowFormat( backupRow );
00962 RowFormat * layout = 0;
00963
00964 if ( collapsed )
00965 srcLayout->setHide( true );
00966
00967 for ( i = 1; i < number; ++i )
00968 {
00969 layout = table->nonDefaultRowFormat( backupRow + i );
00970
00971 layout->copy( *srcLayout );
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 }
00989
00990 rowStyle = 0;
00991 columns = 1;
00992 }
00993
00994 kdDebug(30518) << "Reading in rows done" << endl << endl;
00995
00996 return true;
00997 }
00998
00999 bool OpenCalcImport::readColLayouts( QDomElement & content, Sheet * table )
01000 {
01001 kdDebug(30518) << endl << "Reading in columns..." << endl;
01002
01003 QDomNode colLayout = KoDom::namedItemNS( content, ooNS::table, "table-column" );
01004 int column = 1;
01005
01006 while ( !colLayout.isNull() )
01007 {
01008 if ( colLayout.nodeName() != "table:table-column" )
01009 return true;
01010
01011 QDomElement e = colLayout.toElement();
01012
01013 if ( e.isNull() )
01014 return false;
01015
01016 kdDebug(30518) << "New column: " << column << endl;
01017
01018 int number = 1;
01019 double width = colWidth;
01020 bool collapsed = ( e.attributeNS( ooNS::table, "visibility", QString::null ) == "collapse" );
01021 bool insertPageBreak = false;
01022 Format styleLayout( table, table->doc()->styleManager()->defaultStyle() );
01023
01024 kdDebug(30518) << "Check table:number-columns-repeated" << endl;
01025 if ( e.hasAttributeNS( ooNS::table, "number-columns-repeated" ) )
01026 {
01027 bool ok = true;
01028 number = e.attributeNS( ooNS::table, "number-columns-repeated", QString::null ).toInt( &ok );
01029 if ( !ok )
01030 number = 1;
01031
01032 kdDebug(30518) << "Repeated: " << number << endl;
01033 }
01034
01035 kdDebug(30518) << "Checking table:default-cell-style-name" << endl;
01036 if ( e.hasAttributeNS( ooNS::table, "default-cell-style-name" ) )
01037 {
01038 QString n( e.attributeNS( ooNS::table, "default-cell-style-name", QString::null ) );
01039 kdDebug(30518) << "Has attribute default-cell-style-name: " << n << endl;
01040 Format * defaultStyle = m_defaultStyles[ n ];
01041 if ( !defaultStyle )
01042 {
01043 QString name = e.attributeNS( ooNS::table, "default-cell-style-name", QString::null );
01044 QDomElement * st = m_styles[ name ];
01045
01046 kdDebug(30518) << "Default cell style: " << name << endl;
01047
01048 if ( st && !st->isNull() )
01049 {
01050 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
01051
01052 readInStyle( layout, *st );
01053
01054 m_defaultStyles.insert( name, layout );
01055 kdDebug(30518) << "Insert default cell style: " << name << endl;
01056
01057 defaultStyle = layout;
01058 }
01059 }
01060
01061 if ( defaultStyle )
01062 {
01063
01064 styleLayout.copy( *defaultStyle );
01065 }
01066 }
01067
01068 QDomElement * colStyle = 0;
01069 if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
01070 {
01071 QString style = e.attributeNS( ooNS::table, "style-name", QString::null );
01072 colStyle = m_styles[ style ];
01073
01074 kdDebug(30518) << "Col Style: " << style << endl;
01075 }
01076
01077 QDomNode node;
01078
01079 if ( colStyle )
01080 node = colStyle->firstChild();
01081
01082 while( !node.isNull() )
01083 {
01084 QDomElement property = node.toElement();
01085 if ( !property.isNull() && property.localName() == "properties" && property.namespaceURI() == ooNS::style )
01086 {
01087 if ( property.hasAttributeNS( ooNS::style, "column-width" ) )
01088 {
01089 QString sWidth = property.attributeNS( ooNS::style, "column-width", QString::null );
01090 width = KoUnit::parseValue( property.attributeNS( ooNS::style, "column-width", QString::null ), width );
01091 kdDebug(30518) << "Col Width: " << sWidth << endl;
01092 }
01093
01094 if ( property.hasAttributeNS( ooNS::fo, "break-before" ) )
01095 {
01096 if ( property.attributeNS( ooNS::fo, "break-before", QString::null ) == "page" )
01097 {
01098 insertPageBreak = true;
01099 }
01100 }
01101
01102 loadStyleProperties( &styleLayout, property );
01103 }
01104
01105 node = node.nextSibling();
01106 }
01107
01108 colLayout = colLayout.nextSibling();
01109
01110 if ( colLayout.isNull() && ( number > 30 ) )
01111 number = 30;
01112
01113 for ( int i = 0; i < number; ++i )
01114 {
01115 kdDebug(30518) << "Inserting colLayout: " << column << endl;
01116
01117 ColumnFormat * col = new ColumnFormat( table, column );
01118 col->copy( styleLayout );
01119 col->setWidth( int( width ) );
01120
01121
01122
01123
01124 if ( collapsed )
01125 col->setHide( true );
01126
01127 table->insertColumnFormat( col );
01128 ++column;
01129 }
01130 }
01131
01132 return true;
01133 }
01134
01135 void replaceMacro( QString & text, QString const & old, QString const & newS )
01136 {
01137 int n = text.find( old );
01138 if ( n != -1 )
01139 text = text.replace( n, old.length(), newS );
01140 }
01141
01142 QString getPart( QDomNode const & part )
01143 {
01144 QString result;
01145 QDomElement e = KoDom::namedItemNS( part, ooNS::text, "p" );
01146 while ( !e.isNull() )
01147 {
01148 QString text = e.text();
01149 kdDebug(30518) << "PART: " << text << endl;
01150
01151 QDomElement macro = KoDom::namedItemNS( e, ooNS::text, "time" );
01152 if ( !macro.isNull() )
01153 replaceMacro( text, macro.text(), "<time>" );
01154
01155 macro = KoDom::namedItemNS( e, ooNS::text, "date" );
01156 if ( !macro.isNull() )
01157 replaceMacro( text, macro.text(), "<date>" );
01158
01159 macro = KoDom::namedItemNS( e, ooNS::text, "page-number" );
01160 if ( !macro.isNull() )
01161 replaceMacro( text, macro.text(), "<page>" );
01162
01163 macro = KoDom::namedItemNS( e, ooNS::text, "page-count" );
01164 if ( !macro.isNull() )
01165 replaceMacro( text, macro.text(), "<pages>" );
01166
01167 macro = KoDom::namedItemNS( e, ooNS::text, "sheet-name" );
01168 if ( !macro.isNull() )
01169 replaceMacro( text, macro.text(), "<sheet>" );
01170
01171 macro = KoDom::namedItemNS( e, ooNS::text, "title" );
01172 if ( !macro.isNull() )
01173 replaceMacro( text, macro.text(), "<name>" );
01174
01175 macro = KoDom::namedItemNS( e, ooNS::text, "file-name" );
01176 if ( !macro.isNull() )
01177 replaceMacro( text, macro.text(), "<file>" );
01178
01179 if ( !result.isEmpty() )
01180 result += '\n';
01181 result += text;
01182 e = e.nextSibling().toElement();
01183 }
01184
01185 return result;
01186 }
01187
01188 void OpenCalcImport::loadTableMasterStyle( Sheet * table,
01189 QString const & stylename )
01190 {
01191 kdDebug(30518) << "Loading table master style: " << stylename << endl;
01192
01193 QDomElement * style = m_styles[ stylename ];
01194
01195 if ( !style )
01196 {
01197 kdDebug(30518) << "Master style not found! " << endl;
01198 return;
01199 }
01200
01201 QDomNode header = KoDom::namedItemNS( *style, ooNS::style, "header" );
01202 kdDebug(30518) << "Style header " << endl;
01203
01204 QString hleft, hmiddle, hright;
01205 QString fleft, fmiddle, fright;
01206
01207 if ( !header.isNull() )
01208 {
01209 kdDebug(30518) << "Header exists" << endl;
01210 QDomNode part = KoDom::namedItemNS( header, ooNS::style, "region-left" );
01211 if ( !part.isNull() )
01212 {
01213 hleft = getPart( part );
01214 kdDebug(30518) << "Header left: " << hleft << endl;
01215 }
01216 else
01217 kdDebug(30518) << "Style:region:left doesn't exist!" << endl;
01218 part = KoDom::namedItemNS( header, ooNS::style, "region-center" );
01219 if ( !part.isNull() )
01220 {
01221 hmiddle = getPart( part );
01222 kdDebug(30518) << "Header middle: " << hmiddle << endl;
01223 }
01224 part = KoDom::namedItemNS( header, ooNS::style, "region-right" );
01225 if ( !part.isNull() )
01226 {
01227 hright = getPart( part );
01228 kdDebug(30518) << "Header right: " << hright << endl;
01229 }
01230 }
01231
01232 QDomNode footer = KoDom::namedItemNS( *style, ooNS::style, "footer" );
01233
01234 if ( !footer.isNull() )
01235 {
01236 QDomNode part = KoDom::namedItemNS( footer, ooNS::style, "region-left" );
01237 if ( !part.isNull() )
01238 {
01239 fleft = getPart( part );
01240 kdDebug(30518) << "Footer left: " << fleft << endl;
01241 }
01242 part = KoDom::namedItemNS( footer, ooNS::style, "region-center" );
01243 if ( !part.isNull() )
01244 {
01245 fmiddle = getPart( part );
01246 kdDebug(30518) << "Footer middle: " << fmiddle << endl;
01247 }
01248 part = KoDom::namedItemNS( footer, ooNS::style, "region-right" );
01249 if ( !part.isNull() )
01250 {
01251 fright = getPart( part );
01252 kdDebug(30518) << "Footer right: " << fright << endl;
01253 }
01254 }
01255
01256 table->print()->setHeadFootLine( hleft, hmiddle, hright,
01257 fleft, fmiddle, fright );
01258 if ( style->hasAttributeNS( ooNS::style, "page-master-name" ) )
01259 {
01260 QString masterPageLayoutStyleName=style->attributeNS( ooNS::style, "page-master-name", QString::null );
01261 kdDebug(30518)<<"masterPageLayoutStyleName :"<<masterPageLayoutStyleName<<endl;
01262 QDomElement *masterLayoutStyle = m_styles[masterPageLayoutStyleName];
01263 kdDebug(30518)<<"masterLayoutStyle :"<<masterLayoutStyle<<endl;
01264 if ( !masterLayoutStyle )
01265 return;
01266 KoStyleStack styleStack( ooNS::style, ooNS::fo );
01267 styleStack.push( *masterLayoutStyle );
01268 loadOasisMasterLayoutPage( table, styleStack );
01269 }
01270 }
01271
01272 void OpenCalcImport::loadOasisMasterLayoutPage( Sheet * table,KoStyleStack &styleStack )
01273 {
01274 float left = 0.0;
01275 float right = 0.0;
01276 float top = 0.0;
01277 float bottom = 0.0;
01278 float width = 0.0;
01279 float height = 0.0;
01280 QString orientation = "Portrait";
01281 QString format;
01282
01283
01284
01285
01286 if ( styleStack.hasAttributeNS( ooNS::fo, "page-width" ) )
01287 {
01288 width = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-width" ) ) );
01289 }
01290 if ( styleStack.hasAttributeNS( ooNS::fo, "page-height" ) )
01291 {
01292 height = KoUnit::toMM( KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-height" ) ) );
01293 }
01294 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-top" ) )
01295 {
01296 top = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-top" ) ) );
01297 }
01298 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-bottom" ) )
01299 {
01300 bottom = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-bottom" ) ) );
01301 }
01302 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-left" ) )
01303 {
01304 left = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-left" ) ) );
01305 }
01306 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-right" ) )
01307 {
01308 right = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-right" ) ) );
01309 }
01310 if ( styleStack.hasAttributeNS( ooNS::style, "writing-mode" ) )
01311 {
01312 kdDebug(30518)<<"styleStack.hasAttribute( style:writing-mode ) :"<<styleStack.hasAttributeNS( ooNS::style, "writing-mode" )<<endl;
01313 }
01314 if ( styleStack.hasAttributeNS( ooNS::style, "print-orientation" ) )
01315 {
01316 orientation = ( styleStack.attributeNS( ooNS::style, "print-orientation" )=="landscape" ) ? "Landscape" : "Portrait" ;
01317 }
01318 if ( styleStack.hasAttributeNS( ooNS::style, "num-format" ) )
01319 {
01320 kdDebug(30518)<<" num-format :"<<styleStack.attributeNS( ooNS::style, "num-format" )<<endl;
01321
01322 }
01323 if ( styleStack.hasAttributeNS( ooNS::fo, "background-color" ) )
01324 {
01325
01326 kdDebug(30518)<<" fo:background-color :"<<styleStack.attributeNS( ooNS::fo, "background-color" )<<endl;
01327 }
01328 if ( styleStack.hasAttributeNS( ooNS::style, "print" ) )
01329 {
01330
01331 QString str = styleStack.attributeNS( ooNS::style, "print" );
01332 kdDebug(30518)<<" style:print :"<<str<<endl;
01333
01334 if (str.contains( "headers" ) )
01335 {
01336
01337 }
01338 if ( str.contains( "grid" ) )
01339 {
01340 table->print()->setPrintGrid( true );
01341 }
01342 if ( str.contains( "annotations" ) )
01343 {
01344
01345 }
01346 if ( str.contains( "objects" ) )
01347 {
01348
01349 }
01350 if ( str.contains( "charts" ) )
01351 {
01352
01353 }
01354 if ( str.contains( "drawings" ) )
01355 {
01356
01357 }
01358 if ( str.contains( "formulas" ) )
01359 {
01360 table->setShowFormula(true);
01361 }
01362 if ( str.contains( "zero-values" ) )
01363 {
01364
01365 }
01366 }
01367 if ( styleStack.hasAttributeNS( ooNS::style, "table-centering" ) )
01368 {
01369 QString str = styleStack.attributeNS( ooNS::style, "table-centering" );
01370
01371 kdDebug(30518)<<" styleStack.attribute( style:table-centering ) :"<<str<<endl;
01372 #if 0
01373 if ( str == "horizontal" )
01374 {
01375 }
01376 else if ( str == "vertical" )
01377 {
01378 }
01379 else if ( str == "both" )
01380 {
01381 }
01382 else if ( str == "none" )
01383 {
01384 }
01385 else
01386 kdDebug(30518)<<" table-centering unknown :"<<str<<endl;
01387 #endif
01388 }
01389 format = QString( "%1x%2" ).arg( width ).arg( height );
01390 kdDebug(30518)<<" format : "<<format<<endl;
01391 table->print()->setPaperLayout( left, top, right, bottom, format, orientation );
01392
01393 kdDebug(30518)<<" left margin :"<<left<<" right :"<<right<<" top :"<<top<<" bottom :"<<bottom<<endl;
01394
01395
01396
01397
01398
01399 }
01400
01401
01402 bool OpenCalcImport::parseBody( int numOfTables )
01403 {
01404 QDomElement content = m_content.documentElement();
01405 QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
01406
01407 if ( body.isNull() )
01408 return false;
01409
01410 loadOasisAreaName( body.toElement() );
01411 loadOasisCellValidation( body.toElement() );
01412
01413 Sheet * table;
01414 QDomNode sheet = KoDom::namedItemNS( body, ooNS::table, "table" );
01415
01416 kdDebug()<<" sheet :"<<sheet.isNull()<<endl;
01417 if ( sheet.isNull() )
01418 return false;
01419
01420 while ( !sheet.isNull() )
01421 {
01422 QDomElement t = sheet.toElement();
01423 if ( t.isNull() )
01424 {
01425 sheet = sheet.nextSibling();
01426 continue;
01427 }
01428 if ( t.nodeName() != "table:table" )
01429 {
01430 sheet = sheet.nextSibling();
01431 continue;
01432 }
01433
01434 table = m_doc->map()->addNewSheet();
01435
01436 table->setSheetName( t.attributeNS( ooNS::table, "name", QString::null ), true, false );
01437 kdDebug()<<" table->name()"<<table->name()<<endl;
01438 sheet = sheet.nextSibling();
01439 }
01440
01441 sheet = body.firstChild();
01442
01443 int step = (int) ( 80 / numOfTables );
01444 int progress = 15;
01445
01446 Format::setGlobalColWidth( MM_TO_POINT( 22.7 ) );
01447 Format::setGlobalRowHeight( MM_TO_POINT( 4.3 ) );
01448 kdDebug(30518) << "Global Height: " << MM_TO_POINT( 4.3 ) << ", Global width: " << MM_TO_POINT( 22.7) << endl;
01449
01450 while ( !sheet.isNull() )
01451 {
01452 QDomElement t = sheet.toElement();
01453 if ( t.isNull() )
01454 {
01455 KMessageBox::sorry( 0, i18n( "The file seems to be corrupt. Skipping a table." ) );
01456 sheet = sheet.nextSibling();
01457 continue;
01458 }
01459 if ( t.nodeName() != "table:table" )
01460 {
01461 sheet = sheet.nextSibling();
01462 continue;
01463 }
01464
01465 table = m_doc->map()->findSheet( t.attributeNS( ooNS::table, "name", QString::null ) );
01466 if ( !table )
01467 {
01468 KMessageBox::sorry( 0, i18n( "Skipping a table." ) );
01469 sheet = sheet.nextSibling();
01470 continue;
01471 }
01472
01473 Format * defaultStyle = m_defaultStyles[ "Default" ];
01474 if ( defaultStyle )
01475 {
01476 Cell* defaultCell = table->defaultCell();
01477 kdDebug(30518) << "Copy default style to default cell" << endl;
01478 defaultCell->format()->copy( *defaultStyle );
01479 }
01480 table->setDefaultHeight( MM_TO_POINT( 4.3 ) );
01481 table->setDefaultWidth( MM_TO_POINT( 22.7 ) );
01482
01483 kdDebug(30518) << "Added table: " << t.attributeNS( ooNS::table, "name", QString::null ) << endl;
01484
01485 if ( t.hasAttributeNS( ooNS::table, "style-name" ) )
01486 {
01487 QString style = t.attributeNS( ooNS::table, "style-name", QString::null );
01488 QDomElement * tableStyle = m_styles[ style ];
01489
01490 QDomNode node;
01491
01492 if ( tableStyle )
01493 node = tableStyle->firstChild();
01494
01495 while( !node.isNull() )
01496 {
01497 QDomElement property = node.toElement();
01498 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
01499 {
01500 if ( property.hasAttributeNS( ooNS::table, "display" ) )
01501 {
01502 bool visible = (property.attributeNS( ooNS::table, "display", QString::null ) == "true" ? true : false );
01503 table->hideSheet( !visible );
01504 kdDebug(30518) << "Table: " << table->tableName() << ", hidden: " << !visible << endl;
01505 }
01506 }
01507
01508 node = node.nextSibling();
01509 }
01510
01511 if ( tableStyle && tableStyle->hasAttributeNS( ooNS::style, "master-page-name" ) )
01512 {
01513 QString stylename = "pm" + tableStyle->attributeNS( ooNS::style, "master-page-name", QString::null );
01514
01515 loadTableMasterStyle( table, stylename );
01516
01517 }
01518 }
01519 if ( t.hasAttributeNS( ooNS::table, "print-ranges" ) )
01520 {
01521
01522 QString range = t.attributeNS( ooNS::table, "print-ranges", QString::null );
01523 OpenCalcPoint point( range );
01524
01525 kdDebug(30518) << "Print range: " << point.translation << endl;
01526 KSpread::Range p( point.translation );
01527
01528 kdDebug(30518) << "Print table: " << p.sheetName() << endl;
01529
01530 if ( table->sheetName() == p.sheetName() )
01531 table->print()->setPrintRange( p.range() );
01532 }
01533
01534 if ( !readColLayouts( t, table ) )
01535 return false;
01536
01537 if ( !readRowsAndCells( t, table ) )
01538 return false;
01539
01540 if ( t.hasAttributeNS( ooNS::table, "protected" ) )
01541 {
01542 QCString passwd( "" );
01543 if ( t.hasAttributeNS( ooNS::table, "protection-key" ) )
01544 {
01545 QString p = t.attributeNS( ooNS::table, "protection-key", QString::null );
01546 QCString str( p.latin1() );
01547 kdDebug(30518) << "Decoding password: " << str << endl;
01548 passwd = KCodecs::base64Decode( str );
01549 }
01550 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
01551 table->setProtected( passwd );
01552 }
01553
01554 progress += step;
01555 emit sigProgress( progress );
01556 sheet = sheet.nextSibling();
01557 }
01558
01559 QDomElement b = body.toElement();
01560 if ( b.hasAttributeNS( ooNS::table, "structure-protected" ) )
01561 {
01562 QCString passwd( "" );
01563 if ( b.hasAttributeNS( ooNS::table, "protection-key" ) )
01564 {
01565 QString p = b.attributeNS( ooNS::table, "protection-key", QString::null );
01566 QCString str( p.latin1() );
01567 kdDebug(30518) << "Decoding password: " << str << endl;
01568 passwd = KCodecs::base64Decode( str );
01569 }
01570 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
01571
01572 m_doc->map()->setProtected( passwd );
01573 }
01574
01575 emit sigProgress( 98 );
01576
01577 return true;
01578 }
01579
01580 void OpenCalcImport::insertStyles( QDomElement const & element )
01581 {
01582 if ( element.isNull() )
01583 return;
01584
01585 QDomElement e;
01586 forEachElement( e, element )
01587 {
01588 if ( e.isNull() || !e.hasAttributeNS( ooNS::style, "name" ) )
01589 {
01590 continue;
01591 }
01592
01593 QString name = e.attributeNS( ooNS::style, "name", QString::null );
01594 kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
01595 m_styles.insert( name, new QDomElement( e ) );
01596 }
01597 }
01598
01599
01600 void OpenCalcImport::loadOasisAreaName( const QDomElement&body )
01601 {
01602 QDomNode namedAreas = KoDom::namedItemNS( body, ooNS::table, "named-expressions" );
01603 if ( !namedAreas.isNull() )
01604 {
01605 QDomElement e;
01606 forEachElement( e, namedAreas )
01607 {
01608 if ( e.isNull() || !e.hasAttributeNS( ooNS::table, "name" ) || !e.hasAttributeNS( ooNS::table, "cell-range-address" ) )
01609 {
01610 kdDebug(30518) << "Reading in named area failed" << endl;
01611 continue;
01612 }
01613
01614
01615 QString name = e.attributeNS( ooNS::table, "name", QString::null );
01616 QString areaPoint = e.attributeNS( ooNS::table, "cell-range-address", QString::null );
01617
01618 m_namedAreas.append( name );
01619 kdDebug(30518) << "Reading in named area, name: " << name << ", area: " << areaPoint << endl;
01620
01621 OpenCalcPoint point( areaPoint );
01622 kdDebug(30518) << "Area: " << point.translation << endl;
01623
01624 QString range( point.translation );
01625
01626 if ( point.translation.find( ':' ) == -1 )
01627 {
01628 Point p( point.translation );
01629
01630 int n = range.find( '!' );
01631 if ( n > 0 )
01632 range = range + ":" + range.right( range.length() - n - 1);
01633
01634 kdDebug(30518) << "=> Area: " << range << endl;
01635 }
01636
01637 KSpread::Range p( range );
01638
01639 m_doc->addAreaName( p.range(), name, p.sheetName() );
01640 kdDebug(30518) << "Area range: " << p.sheetName() << endl;
01641 }
01642 }
01643 }
01644
01645 void OpenCalcImport::loadOasisCellValidation( const QDomElement&body )
01646 {
01647 QDomNode validation = KoDom::namedItemNS( body, ooNS::table, "content-validations" );
01648 if ( !validation.isNull() )
01649 {
01650 QDomElement element;
01651 forEachElement( element, validation )
01652 {
01653 if ( element.localName() == "content-validation" ) {
01654 m_validationList.insert( element.attributeNS( ooNS::table, "name", QString::null ), element);
01655 kdDebug(30518)<<" validation found :"<<element.attributeNS( ooNS::table, "name", QString::null )<<endl;
01656 }
01657 else {
01658 kdDebug(30518)<<" Tag not recognize :"<<element.tagName()<<endl;
01659 }
01660 }
01661 }
01662 }
01663
01664
01665 QString * OpenCalcImport::loadFormat( QDomElement * element,
01666 FormatType & formatType,
01667 QString name )
01668 {
01669 if ( !element )
01670 return 0;
01671
01672 int i;
01673 bool ok;
01674
01675 QString * format = 0;
01676 QDomElement e = element->firstChild( ).toElement();
01677 int precision = 0;
01678 int leadingZ = 1;
01679 bool thousandsSep = false;
01680 bool negRed = false;
01681
01682 if ( element->localName() == "time-style" )
01683 formatType = Custom_format;
01684 else if ( element->localName() == "date-style" )
01685 formatType = Custom_format;
01686 else if ( element->localName() == "percentage-style" )
01687 formatType = Custom_format;
01688 else if ( element->localName() == "number-style" )
01689 formatType = Custom_format;
01690 else if ( element->localName() == "currency-style" )
01691 formatType = Custom_format;
01692 else if ( element->localName() == "boolean-style" )
01693 formatType = Custom_format;
01694
01695 if ( !e.isNull() )
01696 format = new QString();
01697
01698
01699
01700
01701
01702
01703 while ( !e.isNull() )
01704 {
01705 if ( e.localName() == "properties" && e.namespaceURI() == ooNS::style )
01706 {
01707 if ( e.hasAttributeNS( ooNS::fo, "color" ) )
01708 negRed = true;
01709 }
01710 else if ( e.localName() == "text" && e.namespaceURI()==ooNS::number)
01711 {
01712 if ( negRed && ( e.text() == "-" ) )
01713 ;
01714 else
01715 format->append( e.text() );
01716 }
01717 else if ( e.localName() == "currency-symbol" && e.namespaceURI()==ooNS::number)
01718 {
01719 QString sym( e.text() );
01720 kdDebug(30518) << "Currency: " << sym << endl;
01721 format->append( sym );
01722
01723 }
01724 else if ( e.localName() == "day-of-week" && e.namespaceURI()==ooNS::number)
01725 {
01726 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01727 {
01728 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01729 format->append( "dddd" );
01730 else
01731 format->append( "ddd" );
01732 }
01733 else
01734 format->append( "ddd" );
01735 }
01736 else if ( e.localName() == "day" && e.namespaceURI()==ooNS::number)
01737 {
01738 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01739 {
01740 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01741 format->append( "dd" );
01742 else
01743 format->append( "d" );
01744 }
01745 else
01746 format->append( "d" );
01747 }
01748 else if ( e.localName() == "month" && e.namespaceURI()==ooNS::number)
01749 {
01750 if ( e.hasAttributeNS( ooNS::number, "textual" ) )
01751 {
01752 if ( e.attributeNS( ooNS::number, "textual", QString::null ) == "true" )
01753 format->append( "mm" );
01754 }
01755
01756 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01757 {
01758 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01759 format->append( "mm" );
01760 else
01761 format->append( "m" );
01762 }
01763 else
01764 format->append( "m" );
01765 }
01766 else if ( e.localName() == "year" && e.namespaceURI()==ooNS::number)
01767 {
01768 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01769 {
01770 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01771 format->append( "yyyy" );
01772 else
01773 format->append( "yy" );
01774 }
01775 else
01776 format->append( "yy" );
01777 }
01778 else if ( e.localName() == "hours" && e.namespaceURI()==ooNS::number)
01779 {
01780 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01781 {
01782 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01783 format->append( "hh" );
01784 else
01785 format->append( "h" );
01786 }
01787 else
01788 format->append( "h" );
01789 }
01790 else if ( e.localName() == "minutes" && e.namespaceURI()==ooNS::number)
01791 {
01792 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01793 {
01794 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01795 format->append( "mm" );
01796 else
01797 format->append( "m" );
01798 }
01799 else
01800 format->append( "m" );
01801 }
01802 else if ( e.localName() == "seconds" && e.namespaceURI()==ooNS::number)
01803 {
01804 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01805 {
01806 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01807 format->append( "ss" );
01808 else
01809 format->append( "s" );
01810 }
01811 else
01812 format->append( "s" );
01813 }
01814 else if ( e.localName() == "am-pm" && e.namespaceURI()==ooNS::number)
01815 {
01816 format->append( "AM/PM" );
01817 }
01818 else if ( e.localName() == "number" && e.namespaceURI()==ooNS::number)
01819 {
01820
01821
01822 if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
01823 {
01824 int d = e.attributeNS( ooNS::number, "decimal-places", QString::null ).toInt( &ok );
01825 if ( ok )
01826 precision = d;
01827 }
01828
01829 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
01830 {
01831 int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
01832 if ( ok )
01833 leadingZ = d;
01834 }
01835
01836 if ( thousandsSep && leadingZ <= 3 )
01837 {
01838 format->append( "#," );
01839 for ( i = leadingZ; i <= 3; ++i )
01840 format->append( '#' );
01841 }
01842
01843 for ( i = 1; i <= leadingZ; ++i )
01844 {
01845 format->append( '0' );
01846 if ( ( i % 3 == 0 ) && thousandsSep )
01847 format->append( ',' );
01848 }
01849
01850 format->append( '.' );
01851 for ( i = 0; i < precision; ++i )
01852 format->append( '0' );
01853 }
01854 else if ( e.localName() == "scientific-number" && e.namespaceURI()==ooNS::number)
01855 {
01856 int exp = 2;
01857
01858 if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
01859 {
01860 int d = e.attributeNS( ooNS::number, "decimal-places", QString::null ).toInt( &ok );
01861 if ( ok )
01862 precision = d;
01863 }
01864
01865 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
01866 {
01867 int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
01868 if ( ok )
01869 leadingZ = d;
01870 }
01871
01872 if ( e.hasAttributeNS( ooNS::number, "min-exponent-digits" ) )
01873 {
01874 int d = e.attributeNS( ooNS::number, "min-exponent-digits", QString::null ).toInt( &ok );
01875 if ( ok )
01876 exp = d;
01877 if ( exp <= 0 )
01878 exp = 1;
01879 }
01880
01881 if ( thousandsSep && leadingZ <= 3 )
01882 {
01883 format->append( "#," );
01884 for ( i = leadingZ; i <= 3; ++i )
01885 format->append( '#' );
01886 }
01887
01888 for ( i = 1; i <= leadingZ; ++i )
01889 {
01890 format->append( '0' );
01891 if ( ( i % 3 == 0 ) && thousandsSep )
01892 format->append( ',' );
01893 }
01894
01895 format->append( '.' );
01896 for ( i = 0; i < precision; ++i )
01897 format->append( '0' );
01898
01899 format->append( "E+" );
01900 for ( i = 0; i < exp; ++i )
01901 format->append( '0' );
01902
01903 formatType = Custom_format;
01904 }
01905 else if ( e.localName() == "fraction" && e.namespaceURI()==ooNS::number)
01906 {
01907 int integer = 0;
01908 int numerator = 1;
01909 int denominator = 1;
01910
01911 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
01912 {
01913 int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
01914 if ( ok )
01915 integer = d;
01916 }
01917 if ( e.hasAttributeNS( ooNS::number, "min-numerator-digits" ) )
01918 {
01919 int d = e.attributeNS( ooNS::number, "min-numerator-digits", QString::null ).toInt( &ok );
01920 if ( ok )
01921 numerator = d;
01922 }
01923 if ( e.hasAttributeNS( ooNS::number, "min-denominator-digits" ) )
01924 {
01925 int d = e.attributeNS( ooNS::number, "min-denominator-digits", QString::null ).toInt( &ok );
01926 if ( ok )
01927 denominator = d;
01928 }
01929
01930 for ( i = 0; i <= integer; ++i )
01931 format->append( '#' );
01932
01933 format->append( ' ' );
01934
01935 for ( i = 0; i <= numerator; ++i )
01936 format->append( '?' );
01937
01938 format->append( '/' );
01939
01940 for ( i = 0; i <= denominator; ++i )
01941 format->append( '?' );
01942 }
01943
01944
01945
01946
01947 e = e.nextSibling().toElement();
01948 }
01949
01950 if ( negRed )
01951 {
01952 QString f( *format );
01953 format->append( ";[Red]" );
01954 format->append( f );
01955 }
01956
01957 kdDebug(30518) << "*** New FormatString: " << *format << endl << endl;
01958
01959 m_formats.insert( name, format );
01960
01961 return format;
01962 }
01963
01964 void OpenCalcImport::loadFontStyle( Format * layout, QDomElement const * font ) const
01965 {
01966 if ( !font || !layout )
01967 return;
01968
01969 kdDebug(30518) << "Copy font style from the layout " << font->tagName() << ", " << font->nodeName() << endl;
01970
01971 if ( font->hasAttributeNS( ooNS::fo, "font-family" ) )
01972 layout->setTextFontFamily( font->attributeNS( ooNS::fo, "font-family", QString::null ) );
01973 if ( font->hasAttributeNS( ooNS::fo, "color" ) )
01974 layout->setTextColor( QColor( font->attributeNS( ooNS::fo, "color", QString::null ) ) );
01975 if ( font->hasAttributeNS( ooNS::fo, "font-size" ) )
01976 layout->setTextFontSize( int( KoUnit::parseValue( font->attributeNS( ooNS::fo, "font-size", QString::null ), 10 ) ) );
01977 else
01978 layout->setTextFontSize( 10 );
01979 if ( font->hasAttributeNS( ooNS::fo, "font-style" ) )
01980 {
01981 kdDebug(30518) << "italic" << endl;
01982 layout->setTextFontItalic( true );
01983 }
01984 if ( font->hasAttributeNS( ooNS::fo, "font-weight" ) )
01985 layout->setTextFontBold( true );
01986 if ( font->hasAttributeNS( ooNS::fo, "text-underline" ) || font->hasAttributeNS( ooNS::style, "text-underline" ) )
01987 layout->setTextFontUnderline( true );
01988 if ( font->hasAttributeNS( ooNS::style, "text-crossing-out" ) )
01989 layout->setTextFontStrike( true );
01990 if ( font->hasAttributeNS( ooNS::style, "font-pitch" ) )
01991 {
01992
01993 }
01994
01995
01996 }
01997
01998 void OpenCalcImport::loadBorder( Format * layout, QString const & borderDef, bPos pos ) const
01999 {
02000 if ( borderDef == "none" )
02001 return;
02002
02003 int p = borderDef.find( ' ' );
02004 if ( p < 0 )
02005 return;
02006
02007 QPen pen;
02008 QString w = borderDef.left( p );
02009 pen.setWidth( (int) KoUnit::parseValue( w ) );
02010
02011
02012 ++p;
02013 int p2 = borderDef.find( ' ', p );
02014 QString s = borderDef.mid( p, p2 - p );
02015
02016 kdDebug(30518) << "Borderstyle: " << s << endl;
02017
02018 if ( s == "solid" || s == "double" )
02019 pen.setStyle( Qt::SolidLine );
02020 else
02021 {
02022 #if 0
02023
02024 pen.setStyle( Qt::DashLine );
02025 pen.setStyle( Qt::DotLine );
02026 pen.setStyle( Qt::DashDotLine );
02027 pen.setStyle( Qt::DashDotDotLine );
02028 #endif
02029 pen.setStyle( Qt::SolidLine );
02030 }
02031
02032 ++p2;
02033 p = borderDef.find( ' ', p2 );
02034 if ( p == -1 )
02035 p = borderDef.length();
02036
02037 pen.setColor( QColor( borderDef.right( p - p2 ) ) );
02038
02039 if ( pos == Left )
02040 layout->setLeftBorderPen( pen );
02041 else if ( pos == Top )
02042 layout->setTopBorderPen( pen );
02043 else if ( pos == Right )
02044 layout->setRightBorderPen( pen );
02045 else if ( pos == Bottom )
02046 layout->setBottomBorderPen( pen );
02047 else if ( pos == Border )
02048 {
02049 layout->setLeftBorderPen( pen );
02050 layout->setTopBorderPen( pen );
02051 layout->setRightBorderPen( pen );
02052 layout->setBottomBorderPen( pen );
02053 }
02054
02055 }
02056
02057 void OpenCalcImport::loadStyleProperties( Format * layout, QDomElement const & property ) const
02058 {
02059 kdDebug(30518) << "*** Loading style properties *****" << endl;
02060
02061 if ( property.hasAttributeNS( ooNS::style, "decimal-places" ) )
02062 {
02063 bool ok = false;
02064 int p = property.attributeNS( ooNS::style, "decimal-places", QString::null ).toInt( &ok );
02065 if (ok )
02066 layout->setPrecision( p );
02067 }
02068
02069 if ( property.hasAttributeNS( ooNS::style, "font-name" ) )
02070 {
02071 QDomElement * font = m_styles[ property.attributeNS( ooNS::style, "font-name", QString::null ) ];
02072 loadFontStyle( layout, font );
02073 }
02074
02075 loadFontStyle( layout, &property );
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 if ( property.hasAttributeNS( ooNS::style, "rotation-angle" ) )
02088 {
02089 bool ok = false;
02090 int a = property.attributeNS( ooNS::style, "rotation-angle", QString::null ).toInt( &ok );
02091 if ( ok )
02092 layout->setAngle( -a + 1 );
02093 }
02094
02095 if ( property.hasAttributeNS( ooNS::fo, "direction" ) )
02096 {
02097 layout->setVerticalText( true );
02098 }
02099 if ( property.hasAttributeNS( ooNS::fo, "text-align" ) )
02100 {
02101 QString s = property.attributeNS( ooNS::fo, "text-align", QString::null );
02102 if ( s == "center" )
02103 layout->setAlign( Format::Center );
02104 else if ( s == "end" )
02105 layout->setAlign( Format::Right );
02106 else if ( s == "start" )
02107 layout->setAlign( Format::Left );
02108 else if ( s == "justify" )
02109 layout->setAlign( Format::Center );
02110 }
02111 if ( property.hasAttributeNS( ooNS::fo, "margin-left" ) )
02112 {
02113 kdDebug(30518)<<"margin-left :"<<KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", QString::null ),0.0 )<<endl;
02114 layout->setIndent( KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", QString::null ),0.0 ) );
02115 }
02116 if ( property.hasAttributeNS( ooNS::fo, "background-color" ) )
02117 layout->setBgColor( QColor( property.attributeNS( ooNS::fo, "background-color", QString::null ) ) );
02118
02119 if ( property.hasAttributeNS( ooNS::style, "print-content" ) )
02120 {
02121 if ( property.attributeNS( ooNS::style, "print-content", QString::null ) == "false" )
02122 layout->setDontPrintText( false );
02123 }
02124 if ( property.hasAttributeNS( ooNS::style, "cell-protect" ) )
02125 {
02126 QString prot( property.attributeNS( ooNS::style, "cell-protect", QString::null ) );
02127 if ( prot == "none" )
02128 {
02129 layout->setNotProtected( true );
02130 layout->setHideFormula( false );
02131 layout->setHideAll( false );
02132 }
02133 else if ( prot == "formula-hidden" )
02134 {
02135 layout->setNotProtected( true );
02136 layout->setHideFormula( true );
02137 layout->setHideAll( false );
02138 }
02139 else if ( prot == "protected formula-hidden" )
02140 {
02141 layout->setNotProtected( false );
02142 layout->setHideFormula( true );
02143 layout->setHideAll( false );
02144 }
02145 else if ( prot == "hidden-and-protected" )
02146 {
02147 layout->setNotProtected( false );
02148 layout->setHideFormula( false );
02149 layout->setHideAll( true );
02150 }
02151 else if ( prot == "protected" )
02152 {
02153 layout->setNotProtected( false );
02154 layout->setHideFormula( false );
02155 layout->setHideAll( false );
02156 }
02157 kdDebug(30518) << "Cell " << prot << endl;
02158 }
02159
02160 if ( property.hasAttributeNS( ooNS::fo, "padding-left" ) )
02161 layout->setIndent( KoUnit::parseValue(property.attributeNS( ooNS::fo, "padding-left", QString::null ) ) );
02162
02163 if ( property.hasAttributeNS( ooNS::fo, "vertical-align" ) )
02164 {
02165 QString s = property.attributeNS( ooNS::fo, "vertical-align", QString::null );
02166 if ( s == "middle" )
02167 layout->setAlignY( Format::Middle );
02168 else if ( s == "bottom" )
02169 layout->setAlignY( Format::Bottom );
02170 else
02171 layout->setAlignY( Format::Top );
02172 }
02173 else
02174 layout->setAlignY( Format::Bottom );
02175
02176 if ( property.hasAttributeNS( ooNS::fo, "wrap-option" ) )
02177 {
02178 layout->setMultiRow( true );
02179
02180
02181
02182
02183
02184
02185 }
02186
02187 if ( property.hasAttributeNS( ooNS::fo, "border-bottom" ) )
02188 {
02189 loadBorder( layout, property.attributeNS( ooNS::fo, "border-bottom", QString::null ), Bottom );
02190
02191 }
02192
02193 if ( property.hasAttributeNS( ooNS::fo, "border-right" ) )
02194 {
02195 loadBorder( layout, property.attributeNS( ooNS::fo, "border-right", QString::null ), Right );
02196
02197 }
02198
02199 if ( property.hasAttributeNS( ooNS::fo, "border-top" ) )
02200 {
02201 loadBorder( layout, property.attributeNS( ooNS::fo, "border-top", QString::null ), Top );
02202
02203 }
02204
02205 if ( property.hasAttributeNS( ooNS::fo, "border-left" ) )
02206 {
02207 loadBorder( layout, property.attributeNS( ooNS::fo, "border-left", QString::null ), Left );
02208
02209 }
02210
02211 if ( property.hasAttributeNS( ooNS::fo, "border" ) )
02212 {
02213 loadBorder( layout, property.attributeNS( ooNS::fo, "border", QString::null ), Border );
02214
02215 }
02216 }
02217
02218 void OpenCalcImport::readInStyle( Format * layout, QDomElement const & style )
02219 {
02220 kdDebug(30518) << "** Reading Style: " << style.tagName() << "; " << style.attributeNS( ooNS::style, "name", QString::null) << endl;
02221 if ( style.localName() == "style" && style.namespaceURI()==ooNS::style)
02222 {
02223 if ( style.hasAttributeNS( ooNS::style, "parent-style-name" ) )
02224 {
02225 Format * cp
02226 = m_defaultStyles.find( style.attributeNS( ooNS::style, "parent-style-name", QString::null ) );
02227 kdDebug(30518) << "Copying layout from " << style.attributeNS( ooNS::style, "parent-style-name", QString::null ) << endl;
02228
02229 if ( cp != 0 )
02230 layout->copy( *cp );
02231 }
02232 else if ( style.hasAttributeNS( ooNS::style, "family") )
02233 {
02234 QString name = style.attribute( "style-family" ) + "default";
02235 Format * cp = m_defaultStyles.find( name );
02236
02237 kdDebug(30518) << "Copying layout from " << name << ", " << !cp << endl;
02238
02239 if ( cp != 0 )
02240 layout->copy( *cp );
02241 }
02242
02243 if ( style.hasAttributeNS( ooNS::style, "data-style-name" ) )
02244 {
02245 QString * format = m_formats[ style.attributeNS( ooNS::style, "data-style-name", QString::null ) ];
02246 FormatType formatType;
02247
02248 if ( !format )
02249 {
02250
02251 QString name( style.attributeNS( ooNS::style, "data-style-name", QString::null ) );
02252 format = loadFormat( m_styles[ name ], formatType, name );
02253 }
02254
02255 if ( format )
02256 {
02257 layout->setFormatString( *format );
02258 layout->setFormatType( formatType );
02259 }
02260
02261
02262 }
02263 }
02264
02265 QDomElement property;
02266 forEachElement( property, style )
02267 {
02268 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
02269 loadStyleProperties( layout, property );
02270
02271 kdDebug(30518) << layout->textFontFamily( 0, 0 ) << endl;
02272 }
02273 }
02274
02275 bool OpenCalcImport::createStyleMap( QDomDocument const & styles )
02276 {
02277 QDomElement content = styles.documentElement();
02278 QDomNode docStyles = KoDom::namedItemNS( content, ooNS::office, "document-styles" );
02279
02280 if ( content.hasAttributeNS( ooNS::office, "version" ) )
02281 {
02282 bool ok = true;
02283 double d = content.attributeNS( ooNS::office, "version", QString::null ).toDouble( &ok );
02284
02285 if ( ok )
02286 {
02287 kdDebug(30518) << "OpenCalc version: " << d << endl;
02288 if ( d > 1.0 )
02289 {
02290 QString message( i18n("This document was created with OpenOffice.org version '%1'. This filter was written for version 1.0. Reading this file could cause strange behavior, crashes or incorrect display of the data. Do you want to continue converting the document?") );
02291 message.arg( content.attributeNS( ooNS::office, "version", QString::null ) );
02292 if ( KMessageBox::warningYesNo( 0, message, i18n( "Unsupported document version" ) ) == KMessageBox::No )
02293 return false;
02294 }
02295 }
02296 }
02297
02298 QDomNode fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
02299
02300 if ( !fontStyles.isNull() )
02301 {
02302 kdDebug(30518) << "Starting reading in font-decl..." << endl;
02303
02304 insertStyles( fontStyles.toElement() );
02305 }
02306 else
02307 kdDebug(30518) << "No items found" << endl;
02308
02309 kdDebug(30518) << "Starting reading in auto:styles" << endl;
02310
02311 QDomNode autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
02312 if ( !autoStyles.isNull() )
02313 insertStyles( autoStyles.toElement() );
02314 else
02315 kdDebug(30518) << "No items found" << endl;
02316
02317
02318 kdDebug(30518) << "Reading in master styles" << endl;
02319
02320 QDomNode masterStyles = KoDom::namedItemNS( content, ooNS::office, "master-styles" );
02321
02322 if ( masterStyles.isNull() )
02323 {
02324 kdDebug(30518) << "Nothing found " << endl;
02325 }
02326
02327 QDomElement master = KoDom::namedItemNS( masterStyles, ooNS::style, "master-page");
02328 if ( !master.isNull() )
02329 {
02330 QString name( "pm" );
02331 name += master.attributeNS( ooNS::style, "name", QString::null );
02332 kdDebug(30518) << "Master style: '" << name << "' loaded " << endl;
02333 m_styles.insert( name, new QDomElement( master ) );
02334
02335 master = master.nextSibling().toElement();
02336 }
02337
02338
02339 kdDebug(30518) << "Starting reading in office:styles" << endl;
02340
02341 QDomNode fixedStyles = KoDom::namedItemNS( content, ooNS::office, "styles" );
02342
02343 kdDebug(30518) << "Reading in default styles" << endl;
02344
02345 QDomNode def = KoDom::namedItemNS( fixedStyles, ooNS::style, "default-style" );
02346 kdDebug()<<" def !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<def.isNull()<<endl;
02347 while ( !def.isNull() )
02348 {
02349 QDomElement e = def.toElement();
02350 kdDebug(30518) << "Style found " << e.nodeName() << ", tag: " << e.tagName() << endl;
02351
02352 if ( e.nodeName() != "style:default-style" )
02353 {
02354 def = def.nextSibling();
02355 continue;
02356 }
02357
02358 if ( !e.isNull() )
02359 {
02360 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
02361
02362 readInStyle( layout, e );
02363 kdDebug(30518) << "Default style " << e.attributeNS( ooNS::style, "family", QString::null ) << "default" << " loaded " << endl;
02364
02365 m_defaultStyles.insert( e.attributeNS( ooNS::style, "family", QString::null ) + "default", layout );
02366
02367
02368 }
02369
02370 def = def.nextSibling();
02371 }
02372
02373 QDomElement defs = KoDom::namedItemNS( fixedStyles, ooNS::style, "style" );
02374 while ( !defs.isNull() )
02375 {
02376 if ( defs.nodeName() != "style:style" )
02377 break;
02378
02379 if ( !defs.hasAttributeNS( ooNS::style, "name" ) )
02380 {
02381
02382 defs = defs.nextSibling().toElement();
02383 continue;
02384 }
02385
02386 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
02387 readInStyle( layout, defs );
02388 kdDebug(30518) << "Default style " << defs.attributeNS( ooNS::style, "name", QString::null ) << " loaded " << endl;
02389
02390 m_defaultStyles.insert( defs.attributeNS( ooNS::style, "name", QString::null ), layout );
02391
02392
02393 defs = defs.nextSibling().toElement();
02394 }
02395
02396 if ( !fixedStyles.isNull() )
02397 insertStyles( fixedStyles.toElement() );
02398
02399 kdDebug(30518) << "Starting reading in automatic styles" << endl;
02400
02401 content = m_content.documentElement();
02402 autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
02403
02404 if ( !autoStyles.isNull() )
02405 insertStyles( autoStyles.toElement() );
02406
02407 fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
02408
02409 if ( !fontStyles.isNull() )
02410 {
02411 kdDebug(30518) << "Starting reading in special font decl" << endl;
02412
02413 insertStyles( fontStyles.toElement() );
02414 }
02415
02416 kdDebug(30518) << "Styles read in." << endl;
02417
02418 return true;
02419 }
02420
02421 void OpenCalcImport::loadOasisValidation( Validity* val, const QString& validationName )
02422 {
02423 kdDebug(30518)<<"validationName:"<<validationName<<endl;
02424 QDomElement element = m_validationList[validationName];
02425 if ( element.hasAttributeNS( ooNS::table, "condition" ) )
02426 {
02427 QString valExpression = element.attributeNS( ooNS::table, "condition", QString::null );
02428 kdDebug(30518)<<" element.attribute( table:condition ) "<<valExpression<<endl;
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442 if ( valExpression.contains( "cell-content-text-length()" ) )
02443 {
02444
02445 valExpression = valExpression.remove("cell-content-text-length()" );
02446 kdDebug(30518)<<" valExpression = :"<<valExpression<<endl;
02447 val->m_restriction = Restriction::TextLength;
02448
02449 loadOasisValidationCondition( val, valExpression );
02450 }
02451
02452 else if ( valExpression.contains( "cell-content-text-length-is-between" ) )
02453 {
02454 val->m_restriction = Restriction::TextLength;
02455 val->m_cond = Conditional::Between;
02456 valExpression = valExpression.remove( "cell-content-text-length-is-between(" );
02457 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
02458 valExpression = valExpression.remove( ")" );
02459 QStringList listVal = QStringList::split( ",", valExpression );
02460 loadOasisValidationValue( val, listVal );
02461 }
02462 else if ( valExpression.contains( "cell-content-text-length-is-not-between" ) )
02463 {
02464 val->m_restriction = Restriction::TextLength;
02465 val->m_cond = Conditional::Different;
02466 valExpression = valExpression.remove( "cell-content-text-length-is-not-between(" );
02467 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
02468 valExpression = valExpression.remove( ")" );
02469 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
02470 QStringList listVal = QStringList::split( ",", valExpression );
02471 loadOasisValidationValue( val, listVal );
02472
02473 }
02474
02475 else
02476 {
02477 if (valExpression.contains( "cell-content-is-whole-number()" ) )
02478 {
02479 val->m_restriction = Restriction::Number;
02480 valExpression = valExpression.remove( "cell-content-is-whole-number() and " );
02481 }
02482 else if (valExpression.contains( "cell-content-is-decimal-number()" ) )
02483 {
02484 val->m_restriction = Restriction::Integer;
02485 valExpression = valExpression.remove( "cell-content-is-decimal-number() and " );
02486 }
02487 else if (valExpression.contains( "cell-content-is-date()" ) )
02488 {
02489 val->m_restriction = Restriction::Date;
02490 valExpression = valExpression.remove( "cell-content-is-date() and " );
02491 }
02492 else if (valExpression.contains( "cell-content-is-time()" ) )
02493 {
02494 val->m_restriction = Restriction::Time;
02495 valExpression = valExpression.remove( "cell-content-is-time() and " );
02496 }
02497 kdDebug(30518)<<"valExpression :"<<valExpression<<endl;
02498
02499 if ( valExpression.contains( "cell-content()" ) )
02500 {
02501 valExpression = valExpression.remove( "cell-content()" );
02502 loadOasisValidationCondition( val, valExpression );
02503 }
02504
02505
02506 if ( valExpression.contains( "cell-content-is-between(" ) )
02507 {
02508 valExpression = valExpression.remove( "cell-content-is-between(" );
02509 valExpression = valExpression.remove( ")" );
02510 QStringList listVal = QStringList::split( "," , valExpression );
02511 loadOasisValidationValue( val, listVal );
02512
02513 val->m_cond = Conditional::Between;
02514 }
02515 if ( valExpression.contains( "cell-content-is-not-between(" ) )
02516 {
02517 valExpression = valExpression.remove( "cell-content-is-not-between(" );
02518 valExpression = valExpression.remove( ")" );
02519 QStringList listVal = QStringList::split( ",", valExpression );
02520 loadOasisValidationValue( val, listVal );
02521 val->m_cond = Conditional::Different;
02522 }
02523 }
02524 }
02525 if ( element.hasAttributeNS( ooNS::table, "allow-empty-cell" ) )
02526 {
02527 val->allowEmptyCell = ( ( element.attributeNS( ooNS::table, "allow-empty-cell", QString::null )=="true" ) ? true : false );
02528
02529 }
02530 if ( element.hasAttributeNS( ooNS::table, "base-cell-address" ) )
02531 {
02532
02533 }
02534
02535 QDomElement help = KoDom::namedItemNS( element, ooNS::table, "help-message" );
02536 if ( !help.isNull() )
02537 {
02538 if ( help.hasAttributeNS( ooNS::table, "title" ) )
02539 val->titleInfo = help.attributeNS( ooNS::table, "title", QString::null );
02540 if ( help.hasAttributeNS( ooNS::table, "display" ) )
02541 val->displayValidationInformation = ( ( help.attributeNS( ooNS::table, "display", QString::null )=="true" ) ? true : false );
02542 QDomElement attrText = KoDom::namedItemNS( help, ooNS::text, "p" );
02543 if ( !attrText.isNull() )
02544 val->messageInfo = attrText.text();
02545 }
02546
02547 QDomElement error = KoDom::namedItemNS( element, ooNS::table, "error-message" );
02548 if ( !error.isNull() )
02549 {
02550 if ( error.hasAttributeNS( ooNS::table, "title" ) )
02551 val->title = error.attributeNS( ooNS::table, "title", QString::null );
02552 if ( error.hasAttributeNS( ooNS::table, "message-type" ) )
02553 {
02554 QString str = error.attributeNS( ooNS::table, "message-type", QString::null );
02555 if ( str == "warning" )
02556 val->m_action = Action::Warning;
02557 else if ( str == "information" )
02558 val->m_action = Action::Information;
02559 else if ( str == "stop" )
02560 val->m_action = Action::Stop;
02561 else
02562 kdDebug(30518)<<"validation : message type unknown :"<<str<<endl;
02563 }
02564
02565 if ( error.hasAttributeNS( ooNS::table, "display" ) )
02566 {
02567 kdDebug(30518)<<" display message :"<<error.attributeNS( ooNS::table, "display", QString::null )<<endl;
02568 val->displayMessage = (error.attributeNS( ooNS::table, "display", QString::null )=="true");
02569 }
02570 QDomElement attrText = KoDom::namedItemNS( error, ooNS::text, "p" );
02571 if ( !attrText.isNull() )
02572 val->message = attrText.text();
02573 }
02574 }
02575
02576 void OpenCalcImport::loadOasisValidationValue( Validity* val, const QStringList &listVal )
02577 {
02578 bool ok = false;
02579 kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
02580
02581 if ( val->m_restriction == Restriction::Date )
02582 {
02583 val->dateMin = QDate::fromString( listVal[0] );
02584 val->dateMax = QDate::fromString( listVal[1] );
02585 }
02586 else if ( val->m_restriction == Restriction::Time )
02587 {
02588 val->timeMin = QTime::fromString( listVal[0] );
02589 val->timeMax = QTime::fromString( listVal[1] );
02590 }
02591 else
02592 {
02593 val->valMin = listVal[0].toDouble(&ok);
02594 if ( !ok )
02595 {
02596 val->valMin = listVal[0].toInt(&ok);
02597 if ( !ok )
02598 kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
02599
02600 #if 0
02601 if ( !ok )
02602 val->valMin = listVal[0];
02603 #endif
02604 }
02605 ok=false;
02606 val->valMax = listVal[1].toDouble(&ok);
02607 if ( !ok )
02608 {
02609 val->valMax = listVal[1].toInt(&ok);
02610 if ( !ok )
02611 kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
02612
02613 #if 0
02614 if ( !ok )
02615 val->valMax = listVal[1];
02616 #endif
02617 }
02618 }
02619 }
02620
02621
02622 void OpenCalcImport::loadOasisValidationCondition( Validity* val,QString &valExpression )
02623 {
02624 QString value;
02625 if (valExpression.contains( "<=" ) )
02626 {
02627 value = valExpression.remove( "<=" );
02628 val->m_cond = Conditional::InferiorEqual;
02629 }
02630 else if (valExpression.contains( ">=" ) )
02631 {
02632 value = valExpression.remove( ">=" );
02633 val->m_cond = Conditional::SuperiorEqual;
02634 }
02635 else if (valExpression.contains( "!=" ) )
02636 {
02637
02638 value = valExpression.remove( "!=" );
02639 val->m_cond = Conditional::DifferentTo;
02640 }
02641 else if ( valExpression.contains( "<" ) )
02642 {
02643 value = valExpression.remove( "<" );
02644 val->m_cond = Conditional::Inferior;
02645 }
02646 else if(valExpression.contains( ">" ) )
02647 {
02648 value = valExpression.remove( ">" );
02649 val->m_cond = Conditional::Superior;
02650 }
02651 else if (valExpression.contains( "=" ) )
02652 {
02653 value = valExpression.remove( "=" );
02654 val->m_cond = Conditional::Equal;
02655 }
02656 else
02657 kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
02658 kdDebug(30518)<<" value :"<<value<<endl;
02659 if ( val->m_restriction == Restriction::Date )
02660 {
02661 val->dateMin = QDate::fromString( value );
02662 }
02663 else if ( val->m_restriction == Restriction::Date )
02664 {
02665 val->timeMin = QTime::fromString( value );
02666 }
02667 else
02668 {
02669 bool ok = false;
02670 val->valMin = value.toDouble(&ok);
02671 if ( !ok )
02672 {
02673 val->valMin = value.toInt(&ok);
02674 if ( !ok )
02675 kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
02676
02677 #if 0
02678 if ( !ok )
02679 val->valMin = value;
02680 #endif
02681 }
02682 }
02683 }
02684
02685
02686 int OpenCalcImport::readMetaData()
02687 {
02688 int result = 5;
02689 KoDocumentInfo * docInfo = m_doc->documentInfo();
02690 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(docInfo->page( "about" ));
02691 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>(docInfo->page( "author" ));
02692
02693 QDomNode meta = KoDom::namedItemNS( m_meta, ooNS::office, "document-meta" );
02694 QDomNode office = KoDom::namedItemNS( meta, ooNS::office, "meta" );
02695
02696 if ( office.isNull() )
02697 return 2;
02698
02699 QDomElement e = KoDom::namedItemNS( office, ooNS::dc, "creator" );
02700 if ( !e.isNull() && !e.text().isEmpty() )
02701 authorPage->setFullName( e.text() );
02702
02703 e = KoDom::namedItemNS( office, ooNS::dc, "title" );
02704 if ( !e.isNull() && !e.text().isEmpty() )
02705 aboutPage->setTitle( e.text() );
02706
02707 e = KoDom::namedItemNS( office, ooNS::dc, "description" );
02708 if ( !e.isNull() && !e.text().isEmpty() )
02709 aboutPage->setAbstract( e.text() );
02710
02711 e = KoDom::namedItemNS( office, ooNS::dc, "subject" );
02712 if ( !e.isNull() && !e.text().isEmpty() )
02713 aboutPage->setSubject( e.text() );
02714
02715 e= KoDom::namedItemNS( office, ooNS::meta, "keywords" );
02716 if ( !e.isNull() )
02717 {
02718 e = KoDom::namedItemNS( e, ooNS::meta, "keyword" );
02719 if ( !e.isNull() && !e.text().isEmpty() )
02720 aboutPage->setKeywords( e.text() );
02721 }
02722
02723 e = KoDom::namedItemNS( office, ooNS::meta, "document-statistic" );
02724 if ( !e.isNull() && e.hasAttributeNS( ooNS::meta, "table-count" ) )
02725 {
02726 bool ok = false;
02727 result = e.attributeNS( ooNS::meta, "table-count", QString::null ).toInt( &ok );
02728 if ( !ok )
02729 result = 5;
02730 }
02731
02732 m_meta.clear();
02733
02734 return result;
02735 }
02736
02737 KoFilter::ConversionStatus OpenCalcImport::convert( QCString const & from, QCString const & to )
02738 {
02739 kdDebug(30518) << "Entering OpenCalc Import filter: " << from << " - " << to << endl;
02740
02741 KoDocument * document = m_chain->outputDocument();
02742 if ( !document )
02743 return KoFilter::StupidError;
02744
02745 if ( !::qt_cast<const KSpread::Doc *>( document ) )
02746 {
02747 kdWarning(30518) << "document isn't a KSpread::Doc but a " << document->className() << endl;
02748 return KoFilter::NotImplemented;
02749 }
02750
02751 if ( ( from != "application/vnd.sun.xml.calc" && from != "application/vnd.sun.xml.calc.template") || to != "application/x-kspread" )
02752 {
02753 kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl;
02754 return KoFilter::NotImplemented;
02755 }
02756
02757 m_doc = ( Doc * ) document;
02758
02759 if ( m_doc->mimeType() != "application/x-kspread" )
02760 {
02761 kdWarning(30518) << "Invalid document mimetype " << m_doc->mimeType() << endl;
02762 return KoFilter::NotImplemented;
02763 }
02764
02765 kdDebug(30518) << "Opening file " << endl;
02766
02767 KoFilter::ConversionStatus preStatus = openFile();
02768
02769 if ( preStatus != KoFilter::OK )
02770 return preStatus;
02771
02772 emit sigProgress( 13 );
02773 int tables = readMetaData();
02774
02775 emit sigProgress( 15 );
02776
02777 if ( !parseBody( tables ) )
02778 return KoFilter::StupidError;
02779
02780 emit sigProgress( 100 );
02781 return KoFilter::OK;
02782 }
02783
02784 KoFilter::ConversionStatus OpenCalcImport::openFile()
02785 {
02786 KoStore * store = KoStore::createStore( m_chain->inputFile(), KoStore::Read);
02787
02788 kdDebug(30518) << "Store created" << endl;
02789
02790 if ( !store )
02791 {
02792 kdWarning(30518) << "Couldn't open the requested file." << endl;
02793 return KoFilter::FileNotFound;
02794 }
02795
02796 kdDebug(30518) << "Trying to open content.xml" << endl;
02797 QString messageError;
02798 loadAndParse( m_content, "content.xml", store);
02799 kdDebug(30518) << "Opened" << endl;
02800
02801 QDomDocument styles;
02802 kdDebug(30518) << "file content.xml loaded " << endl;
02803
02804 loadAndParse( styles, "styles.xml", store);
02805
02806 loadAndParse( m_meta, "meta.xml", store);
02807 loadAndParse( m_settings, "settings.xml", store);
02808
02809 delete store;
02810
02811 emit sigProgress( 10 );
02812
02813 if ( !createStyleMap( styles ) )
02814 return KoFilter::UserCancelled;
02815
02816 return KoFilter::OK;
02817 }
02818
02819 KoFilter::ConversionStatus OpenCalcImport::loadAndParse( QDomDocument& doc, const QString& fileName,KoStore *m_store )
02820 {
02821 return OoUtils::loadAndParse( fileName, doc, m_store);
02822 }
02823
02824 #include "opencalcimport.moc"
02825