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 = -1.0;
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 if ( width != -1.0 )
01120 col->setWidth( int( width ) );
01121
01122
01123
01124
01125 if ( collapsed )
01126 col->setHide( true );
01127
01128 table->insertColumnFormat( col );
01129 ++column;
01130 }
01131 }
01132
01133 return true;
01134 }
01135
01136 void replaceMacro( QString & text, QString const & old, QString const & newS )
01137 {
01138 int n = text.find( old );
01139 if ( n != -1 )
01140 text = text.replace( n, old.length(), newS );
01141 }
01142
01143 QString getPart( QDomNode const & part )
01144 {
01145 QString result;
01146 QDomElement e = KoDom::namedItemNS( part, ooNS::text, "p" );
01147 while ( !e.isNull() )
01148 {
01149 QString text = e.text();
01150 kdDebug(30518) << "PART: " << text << endl;
01151
01152 QDomElement macro = KoDom::namedItemNS( e, ooNS::text, "time" );
01153 if ( !macro.isNull() )
01154 replaceMacro( text, macro.text(), "<time>" );
01155
01156 macro = KoDom::namedItemNS( e, ooNS::text, "date" );
01157 if ( !macro.isNull() )
01158 replaceMacro( text, macro.text(), "<date>" );
01159
01160 macro = KoDom::namedItemNS( e, ooNS::text, "page-number" );
01161 if ( !macro.isNull() )
01162 replaceMacro( text, macro.text(), "<page>" );
01163
01164 macro = KoDom::namedItemNS( e, ooNS::text, "page-count" );
01165 if ( !macro.isNull() )
01166 replaceMacro( text, macro.text(), "<pages>" );
01167
01168 macro = KoDom::namedItemNS( e, ooNS::text, "sheet-name" );
01169 if ( !macro.isNull() )
01170 replaceMacro( text, macro.text(), "<sheet>" );
01171
01172 macro = KoDom::namedItemNS( e, ooNS::text, "title" );
01173 if ( !macro.isNull() )
01174 replaceMacro( text, macro.text(), "<name>" );
01175
01176 macro = KoDom::namedItemNS( e, ooNS::text, "file-name" );
01177 if ( !macro.isNull() )
01178 replaceMacro( text, macro.text(), "<file>" );
01179
01180 if ( !result.isEmpty() )
01181 result += '\n';
01182 result += text;
01183 e = e.nextSibling().toElement();
01184 }
01185
01186 return result;
01187 }
01188
01189 void OpenCalcImport::loadTableMasterStyle( Sheet * table,
01190 QString const & stylename )
01191 {
01192 kdDebug(30518) << "Loading table master style: " << stylename << endl;
01193
01194 QDomElement * style = m_styles[ stylename ];
01195
01196 if ( !style )
01197 {
01198 kdDebug(30518) << "Master style not found! " << endl;
01199 return;
01200 }
01201
01202 QDomNode header = KoDom::namedItemNS( *style, ooNS::style, "header" );
01203 kdDebug(30518) << "Style header " << endl;
01204
01205 QString hleft, hmiddle, hright;
01206 QString fleft, fmiddle, fright;
01207
01208 if ( !header.isNull() )
01209 {
01210 kdDebug(30518) << "Header exists" << endl;
01211 QDomNode part = KoDom::namedItemNS( header, ooNS::style, "region-left" );
01212 if ( !part.isNull() )
01213 {
01214 hleft = getPart( part );
01215 kdDebug(30518) << "Header left: " << hleft << endl;
01216 }
01217 else
01218 kdDebug(30518) << "Style:region:left doesn't exist!" << endl;
01219 part = KoDom::namedItemNS( header, ooNS::style, "region-center" );
01220 if ( !part.isNull() )
01221 {
01222 hmiddle = getPart( part );
01223 kdDebug(30518) << "Header middle: " << hmiddle << endl;
01224 }
01225 part = KoDom::namedItemNS( header, ooNS::style, "region-right" );
01226 if ( !part.isNull() )
01227 {
01228 hright = getPart( part );
01229 kdDebug(30518) << "Header right: " << hright << endl;
01230 }
01231 }
01232
01233 QDomNode footer = KoDom::namedItemNS( *style, ooNS::style, "footer" );
01234
01235 if ( !footer.isNull() )
01236 {
01237 QDomNode part = KoDom::namedItemNS( footer, ooNS::style, "region-left" );
01238 if ( !part.isNull() )
01239 {
01240 fleft = getPart( part );
01241 kdDebug(30518) << "Footer left: " << fleft << endl;
01242 }
01243 part = KoDom::namedItemNS( footer, ooNS::style, "region-center" );
01244 if ( !part.isNull() )
01245 {
01246 fmiddle = getPart( part );
01247 kdDebug(30518) << "Footer middle: " << fmiddle << endl;
01248 }
01249 part = KoDom::namedItemNS( footer, ooNS::style, "region-right" );
01250 if ( !part.isNull() )
01251 {
01252 fright = getPart( part );
01253 kdDebug(30518) << "Footer right: " << fright << endl;
01254 }
01255 }
01256
01257 table->print()->setHeadFootLine( hleft, hmiddle, hright,
01258 fleft, fmiddle, fright );
01259 if ( style->hasAttributeNS( ooNS::style, "page-master-name" ) )
01260 {
01261 QString masterPageLayoutStyleName=style->attributeNS( ooNS::style, "page-master-name", QString::null );
01262 kdDebug(30518)<<"masterPageLayoutStyleName :"<<masterPageLayoutStyleName<<endl;
01263 QDomElement *masterLayoutStyle = m_styles[masterPageLayoutStyleName];
01264 kdDebug(30518)<<"masterLayoutStyle :"<<masterLayoutStyle<<endl;
01265 if ( !masterLayoutStyle )
01266 return;
01267 KoStyleStack styleStack( ooNS::style, ooNS::fo );
01268 styleStack.push( *masterLayoutStyle );
01269 loadOasisMasterLayoutPage( table, styleStack );
01270 }
01271 }
01272
01273 void OpenCalcImport::loadOasisMasterLayoutPage( Sheet * table,KoStyleStack &styleStack )
01274 {
01275 float left = 0.0;
01276 float right = 0.0;
01277 float top = 0.0;
01278 float bottom = 0.0;
01279 float width = 0.0;
01280 float height = 0.0;
01281 QString orientation = "Portrait";
01282 QString format;
01283
01284
01285
01286
01287 if ( styleStack.hasAttributeNS( ooNS::fo, "page-width" ) )
01288 {
01289 width = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-width" ) ) );
01290 }
01291 if ( styleStack.hasAttributeNS( ooNS::fo, "page-height" ) )
01292 {
01293 height = KoUnit::toMM( KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-height" ) ) );
01294 }
01295 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-top" ) )
01296 {
01297 top = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-top" ) ) );
01298 }
01299 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-bottom" ) )
01300 {
01301 bottom = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-bottom" ) ) );
01302 }
01303 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-left" ) )
01304 {
01305 left = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-left" ) ) );
01306 }
01307 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-right" ) )
01308 {
01309 right = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-right" ) ) );
01310 }
01311 if ( styleStack.hasAttributeNS( ooNS::style, "writing-mode" ) )
01312 {
01313 kdDebug(30518)<<"styleStack.hasAttribute( style:writing-mode ) :"<<styleStack.hasAttributeNS( ooNS::style, "writing-mode" )<<endl;
01314 }
01315 if ( styleStack.hasAttributeNS( ooNS::style, "print-orientation" ) )
01316 {
01317 orientation = ( styleStack.attributeNS( ooNS::style, "print-orientation" )=="landscape" ) ? "Landscape" : "Portrait" ;
01318 }
01319 if ( styleStack.hasAttributeNS( ooNS::style, "num-format" ) )
01320 {
01321 kdDebug(30518)<<" num-format :"<<styleStack.attributeNS( ooNS::style, "num-format" )<<endl;
01322
01323 }
01324 if ( styleStack.hasAttributeNS( ooNS::fo, "background-color" ) )
01325 {
01326
01327 kdDebug(30518)<<" fo:background-color :"<<styleStack.attributeNS( ooNS::fo, "background-color" )<<endl;
01328 }
01329 if ( styleStack.hasAttributeNS( ooNS::style, "print" ) )
01330 {
01331
01332 QString str = styleStack.attributeNS( ooNS::style, "print" );
01333 kdDebug(30518)<<" style:print :"<<str<<endl;
01334
01335 if (str.contains( "headers" ) )
01336 {
01337
01338 }
01339 if ( str.contains( "grid" ) )
01340 {
01341 table->print()->setPrintGrid( true );
01342 }
01343 if ( str.contains( "annotations" ) )
01344 {
01345
01346 }
01347 if ( str.contains( "objects" ) )
01348 {
01349
01350 }
01351 if ( str.contains( "charts" ) )
01352 {
01353
01354 }
01355 if ( str.contains( "drawings" ) )
01356 {
01357
01358 }
01359 if ( str.contains( "formulas" ) )
01360 {
01361 table->setShowFormula(true);
01362 }
01363 if ( str.contains( "zero-values" ) )
01364 {
01365
01366 }
01367 }
01368 if ( styleStack.hasAttributeNS( ooNS::style, "table-centering" ) )
01369 {
01370 QString str = styleStack.attributeNS( ooNS::style, "table-centering" );
01371
01372 kdDebug(30518)<<" styleStack.attribute( style:table-centering ) :"<<str<<endl;
01373 #if 0
01374 if ( str == "horizontal" )
01375 {
01376 }
01377 else if ( str == "vertical" )
01378 {
01379 }
01380 else if ( str == "both" )
01381 {
01382 }
01383 else if ( str == "none" )
01384 {
01385 }
01386 else
01387 kdDebug(30518)<<" table-centering unknown :"<<str<<endl;
01388 #endif
01389 }
01390 format = QString( "%1x%2" ).arg( width ).arg( height );
01391 kdDebug(30518)<<" format : "<<format<<endl;
01392 table->print()->setPaperLayout( left, top, right, bottom, format, orientation );
01393
01394 kdDebug(30518)<<" left margin :"<<left<<" right :"<<right<<" top :"<<top<<" bottom :"<<bottom<<endl;
01395
01396
01397
01398
01399
01400 }
01401
01402
01403 bool OpenCalcImport::parseBody( int numOfTables )
01404 {
01405 QDomElement content = m_content.documentElement();
01406 QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
01407
01408 if ( body.isNull() )
01409 return false;
01410
01411 loadOasisAreaName( body.toElement() );
01412 loadOasisCellValidation( body.toElement() );
01413
01414 Sheet * table;
01415 QDomNode sheet = KoDom::namedItemNS( body, ooNS::table, "table" );
01416
01417 kdDebug()<<" sheet :"<<sheet.isNull()<<endl;
01418 if ( sheet.isNull() )
01419 return false;
01420
01421 while ( !sheet.isNull() )
01422 {
01423 QDomElement t = sheet.toElement();
01424 if ( t.isNull() )
01425 {
01426 sheet = sheet.nextSibling();
01427 continue;
01428 }
01429 if ( t.nodeName() != "table:table" )
01430 {
01431 sheet = sheet.nextSibling();
01432 continue;
01433 }
01434
01435 table = m_doc->map()->addNewSheet();
01436
01437 table->setSheetName( t.attributeNS( ooNS::table, "name", QString::null ), true, false );
01438 kdDebug()<<" table->name()"<<table->name()<<endl;
01439 sheet = sheet.nextSibling();
01440 }
01441
01442 sheet = body.firstChild();
01443
01444 int step = (int) ( 80 / numOfTables );
01445 int progress = 15;
01446
01447 Format::setGlobalColWidth( MM_TO_POINT( 22.7 ) );
01448 Format::setGlobalRowHeight( MM_TO_POINT( 4.3 ) );
01449 kdDebug(30518) << "Global Height: " << MM_TO_POINT( 4.3 ) << ", Global width: " << MM_TO_POINT( 22.7) << endl;
01450
01451 while ( !sheet.isNull() )
01452 {
01453 QDomElement t = sheet.toElement();
01454 if ( t.isNull() )
01455 {
01456 KMessageBox::sorry( 0, i18n( "The file seems to be corrupt. Skipping a table." ) );
01457 sheet = sheet.nextSibling();
01458 continue;
01459 }
01460 if ( t.nodeName() != "table:table" )
01461 {
01462 sheet = sheet.nextSibling();
01463 continue;
01464 }
01465
01466 table = m_doc->map()->findSheet( t.attributeNS( ooNS::table, "name", QString::null ) );
01467 if ( !table )
01468 {
01469 KMessageBox::sorry( 0, i18n( "Skipping a table." ) );
01470 sheet = sheet.nextSibling();
01471 continue;
01472 }
01473
01474 Format * defaultStyle = m_defaultStyles[ "Default" ];
01475 if ( defaultStyle )
01476 {
01477 Cell* defaultCell = table->defaultCell();
01478 kdDebug(30518) << "Copy default style to default cell" << endl;
01479 defaultCell->format()->copy( *defaultStyle );
01480 }
01481 table->setDefaultHeight( MM_TO_POINT( 4.3 ) );
01482 table->setDefaultWidth( MM_TO_POINT( 22.7 ) );
01483
01484 kdDebug(30518) << "Added table: " << t.attributeNS( ooNS::table, "name", QString::null ) << endl;
01485
01486 if ( t.hasAttributeNS( ooNS::table, "style-name" ) )
01487 {
01488 QString style = t.attributeNS( ooNS::table, "style-name", QString::null );
01489 QDomElement * tableStyle = m_styles[ style ];
01490
01491 QDomNode node;
01492
01493 if ( tableStyle )
01494 node = tableStyle->firstChild();
01495
01496 while( !node.isNull() )
01497 {
01498 QDomElement property = node.toElement();
01499 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
01500 {
01501 if ( property.hasAttributeNS( ooNS::table, "display" ) )
01502 {
01503 bool visible = (property.attributeNS( ooNS::table, "display", QString::null ) == "true" ? true : false );
01504 table->hideSheet( !visible );
01505 kdDebug(30518) << "Table: " << table->tableName() << ", hidden: " << !visible << endl;
01506 }
01507 }
01508
01509 node = node.nextSibling();
01510 }
01511
01512 if ( tableStyle && tableStyle->hasAttributeNS( ooNS::style, "master-page-name" ) )
01513 {
01514 QString stylename = "pm" + tableStyle->attributeNS( ooNS::style, "master-page-name", QString::null );
01515
01516 loadTableMasterStyle( table, stylename );
01517
01518 }
01519 }
01520 if ( t.hasAttributeNS( ooNS::table, "print-ranges" ) )
01521 {
01522
01523 QString range = t.attributeNS( ooNS::table, "print-ranges", QString::null );
01524 OpenCalcPoint point( range );
01525
01526 kdDebug(30518) << "Print range: " << point.translation << endl;
01527 KSpread::Range p( point.translation );
01528
01529 kdDebug(30518) << "Print table: " << p.sheetName() << endl;
01530
01531 if ( table->sheetName() == p.sheetName() )
01532 table->print()->setPrintRange( p.range() );
01533 }
01534
01535 if ( !readColLayouts( t, table ) )
01536 return false;
01537
01538 if ( !readRowsAndCells( t, table ) )
01539 return false;
01540
01541 if ( t.hasAttributeNS( ooNS::table, "protected" ) )
01542 {
01543 QCString passwd( "" );
01544 if ( t.hasAttributeNS( ooNS::table, "protection-key" ) )
01545 {
01546 QString p = t.attributeNS( ooNS::table, "protection-key", QString::null );
01547 QCString str( p.latin1() );
01548 kdDebug(30518) << "Decoding password: " << str << endl;
01549 passwd = KCodecs::base64Decode( str );
01550 }
01551 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
01552 table->setProtected( passwd );
01553 }
01554
01555 progress += step;
01556 emit sigProgress( progress );
01557 sheet = sheet.nextSibling();
01558 }
01559
01560 QDomElement b = body.toElement();
01561 if ( b.hasAttributeNS( ooNS::table, "structure-protected" ) )
01562 {
01563 QCString passwd( "" );
01564 if ( b.hasAttributeNS( ooNS::table, "protection-key" ) )
01565 {
01566 QString p = b.attributeNS( ooNS::table, "protection-key", QString::null );
01567 QCString str( p.latin1() );
01568 kdDebug(30518) << "Decoding password: " << str << endl;
01569 passwd = KCodecs::base64Decode( str );
01570 }
01571 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
01572
01573 m_doc->map()->setProtected( passwd );
01574 }
01575
01576 emit sigProgress( 98 );
01577
01578 return true;
01579 }
01580
01581 void OpenCalcImport::insertStyles( QDomElement const & element )
01582 {
01583 if ( element.isNull() )
01584 return;
01585
01586 QDomElement e;
01587 forEachElement( e, element )
01588 {
01589 if ( e.isNull() || !e.hasAttributeNS( ooNS::style, "name" ) )
01590 {
01591 continue;
01592 }
01593
01594 QString name = e.attributeNS( ooNS::style, "name", QString::null );
01595 kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
01596 m_styles.insert( name, new QDomElement( e ) );
01597 }
01598 }
01599
01600
01601 void OpenCalcImport::loadOasisAreaName( const QDomElement&body )
01602 {
01603 QDomNode namedAreas = KoDom::namedItemNS( body, ooNS::table, "named-expressions" );
01604 if ( !namedAreas.isNull() )
01605 {
01606 QDomElement e;
01607 forEachElement( e, namedAreas )
01608 {
01609 if ( e.isNull() || !e.hasAttributeNS( ooNS::table, "name" ) || !e.hasAttributeNS( ooNS::table, "cell-range-address" ) )
01610 {
01611 kdDebug(30518) << "Reading in named area failed" << endl;
01612 continue;
01613 }
01614
01615
01616 QString name = e.attributeNS( ooNS::table, "name", QString::null );
01617 QString areaPoint = e.attributeNS( ooNS::table, "cell-range-address", QString::null );
01618
01619 m_namedAreas.append( name );
01620 kdDebug(30518) << "Reading in named area, name: " << name << ", area: " << areaPoint << endl;
01621
01622 OpenCalcPoint point( areaPoint );
01623 kdDebug(30518) << "Area: " << point.translation << endl;
01624
01625 QString range( point.translation );
01626
01627 if ( point.translation.find( ':' ) == -1 )
01628 {
01629 Point p( point.translation );
01630
01631 int n = range.find( '!' );
01632 if ( n > 0 )
01633 range = range + ":" + range.right( range.length() - n - 1);
01634
01635 kdDebug(30518) << "=> Area: " << range << endl;
01636 }
01637
01638 KSpread::Range p( range );
01639
01640 m_doc->addAreaName( p.range(), name, p.sheetName() );
01641 kdDebug(30518) << "Area range: " << p.sheetName() << endl;
01642 }
01643 }
01644 }
01645
01646 void OpenCalcImport::loadOasisCellValidation( const QDomElement&body )
01647 {
01648 QDomNode validation = KoDom::namedItemNS( body, ooNS::table, "content-validations" );
01649 if ( !validation.isNull() )
01650 {
01651 QDomElement element;
01652 forEachElement( element, validation )
01653 {
01654 if ( element.localName() == "content-validation" ) {
01655 m_validationList.insert( element.attributeNS( ooNS::table, "name", QString::null ), element);
01656 kdDebug(30518)<<" validation found :"<<element.attributeNS( ooNS::table, "name", QString::null )<<endl;
01657 }
01658 else {
01659 kdDebug(30518)<<" Tag not recognize :"<<element.tagName()<<endl;
01660 }
01661 }
01662 }
01663 }
01664
01665
01666 QString * OpenCalcImport::loadFormat( QDomElement * element,
01667 FormatType & formatType,
01668 QString name )
01669 {
01670 if ( !element )
01671 return 0;
01672
01673 int i;
01674 bool ok;
01675
01676 QString * format = 0;
01677 QDomElement e = element->firstChild( ).toElement();
01678 int precision = 0;
01679 int leadingZ = 1;
01680 bool thousandsSep = false;
01681 bool negRed = false;
01682
01683 if ( element->localName() == "time-style" )
01684 formatType = Custom_format;
01685 else if ( element->localName() == "date-style" )
01686 formatType = Custom_format;
01687 else if ( element->localName() == "percentage-style" )
01688 formatType = Custom_format;
01689 else if ( element->localName() == "number-style" )
01690 formatType = Custom_format;
01691 else if ( element->localName() == "currency-style" )
01692 formatType = Custom_format;
01693 else if ( element->localName() == "boolean-style" )
01694 formatType = Custom_format;
01695
01696 if ( !e.isNull() )
01697 format = new QString();
01698
01699
01700
01701
01702
01703
01704 while ( !e.isNull() )
01705 {
01706 if ( e.localName() == "properties" && e.namespaceURI() == ooNS::style )
01707 {
01708 if ( e.hasAttributeNS( ooNS::fo, "color" ) )
01709 negRed = true;
01710 }
01711 else if ( e.localName() == "text" && e.namespaceURI()==ooNS::number)
01712 {
01713 if ( negRed && ( e.text() == "-" ) )
01714 ;
01715 else
01716 format->append( e.text() );
01717 }
01718 else if ( e.localName() == "currency-symbol" && e.namespaceURI()==ooNS::number)
01719 {
01720 QString sym( e.text() );
01721 kdDebug(30518) << "Currency: " << sym << endl;
01722 format->append( sym );
01723
01724 }
01725 else if ( e.localName() == "day-of-week" && e.namespaceURI()==ooNS::number)
01726 {
01727 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01728 {
01729 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01730 format->append( "dddd" );
01731 else
01732 format->append( "ddd" );
01733 }
01734 else
01735 format->append( "ddd" );
01736 }
01737 else if ( e.localName() == "day" && e.namespaceURI()==ooNS::number)
01738 {
01739 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01740 {
01741 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01742 format->append( "dd" );
01743 else
01744 format->append( "d" );
01745 }
01746 else
01747 format->append( "d" );
01748 }
01749 else if ( e.localName() == "month" && e.namespaceURI()==ooNS::number)
01750 {
01751 if ( e.hasAttributeNS( ooNS::number, "textual" ) )
01752 {
01753 if ( e.attributeNS( ooNS::number, "textual", QString::null ) == "true" )
01754 format->append( "mm" );
01755 }
01756
01757 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01758 {
01759 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01760 format->append( "mm" );
01761 else
01762 format->append( "m" );
01763 }
01764 else
01765 format->append( "m" );
01766 }
01767 else if ( e.localName() == "year" && e.namespaceURI()==ooNS::number)
01768 {
01769 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01770 {
01771 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01772 format->append( "yyyy" );
01773 else
01774 format->append( "yy" );
01775 }
01776 else
01777 format->append( "yy" );
01778 }
01779 else if ( e.localName() == "hours" && e.namespaceURI()==ooNS::number)
01780 {
01781 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01782 {
01783 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01784 format->append( "hh" );
01785 else
01786 format->append( "h" );
01787 }
01788 else
01789 format->append( "h" );
01790 }
01791 else if ( e.localName() == "minutes" && e.namespaceURI()==ooNS::number)
01792 {
01793 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01794 {
01795 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01796 format->append( "mm" );
01797 else
01798 format->append( "m" );
01799 }
01800 else
01801 format->append( "m" );
01802 }
01803 else if ( e.localName() == "seconds" && e.namespaceURI()==ooNS::number)
01804 {
01805 if ( e.hasAttributeNS( ooNS::number, "style" ) )
01806 {
01807 if ( e.attributeNS( ooNS::number, "style", QString::null ) == "long" )
01808 format->append( "ss" );
01809 else
01810 format->append( "s" );
01811 }
01812 else
01813 format->append( "s" );
01814 }
01815 else if ( e.localName() == "am-pm" && e.namespaceURI()==ooNS::number)
01816 {
01817 format->append( "AM/PM" );
01818 }
01819 else if ( e.localName() == "number" && e.namespaceURI()==ooNS::number)
01820 {
01821
01822
01823 if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
01824 {
01825 int d = e.attributeNS( ooNS::number, "decimal-places", QString::null ).toInt( &ok );
01826 if ( ok )
01827 precision = d;
01828 }
01829
01830 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
01831 {
01832 int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
01833 if ( ok )
01834 leadingZ = d;
01835 }
01836
01837 if ( thousandsSep && leadingZ <= 3 )
01838 {
01839 format->append( "#," );
01840 for ( i = leadingZ; i <= 3; ++i )
01841 format->append( '#' );
01842 }
01843
01844 for ( i = 1; i <= leadingZ; ++i )
01845 {
01846 format->append( '0' );
01847 if ( ( i % 3 == 0 ) && thousandsSep )
01848 format->append( ',' );
01849 }
01850
01851 format->append( '.' );
01852 for ( i = 0; i < precision; ++i )
01853 format->append( '0' );
01854 }
01855 else if ( e.localName() == "scientific-number" && e.namespaceURI()==ooNS::number)
01856 {
01857 int exp = 2;
01858
01859 if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
01860 {
01861 int d = e.attributeNS( ooNS::number, "decimal-places", QString::null ).toInt( &ok );
01862 if ( ok )
01863 precision = d;
01864 }
01865
01866 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
01867 {
01868 int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
01869 if ( ok )
01870 leadingZ = d;
01871 }
01872
01873 if ( e.hasAttributeNS( ooNS::number, "min-exponent-digits" ) )
01874 {
01875 int d = e.attributeNS( ooNS::number, "min-exponent-digits", QString::null ).toInt( &ok );
01876 if ( ok )
01877 exp = d;
01878 if ( exp <= 0 )
01879 exp = 1;
01880 }
01881
01882 if ( thousandsSep && leadingZ <= 3 )
01883 {
01884 format->append( "#," );
01885 for ( i = leadingZ; i <= 3; ++i )
01886 format->append( '#' );
01887 }
01888
01889 for ( i = 1; i <= leadingZ; ++i )
01890 {
01891 format->append( '0' );
01892 if ( ( i % 3 == 0 ) && thousandsSep )
01893 format->append( ',' );
01894 }
01895
01896 format->append( '.' );
01897 for ( i = 0; i < precision; ++i )
01898 format->append( '0' );
01899
01900 format->append( "E+" );
01901 for ( i = 0; i < exp; ++i )
01902 format->append( '0' );
01903
01904 formatType = Custom_format;
01905 }
01906 else if ( e.localName() == "fraction" && e.namespaceURI()==ooNS::number)
01907 {
01908 int integer = 0;
01909 int numerator = 1;
01910 int denominator = 1;
01911
01912 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
01913 {
01914 int d = e.attributeNS( ooNS::number, "min-integer-digits", QString::null ).toInt( &ok );
01915 if ( ok )
01916 integer = d;
01917 }
01918 if ( e.hasAttributeNS( ooNS::number, "min-numerator-digits" ) )
01919 {
01920 int d = e.attributeNS( ooNS::number, "min-numerator-digits", QString::null ).toInt( &ok );
01921 if ( ok )
01922 numerator = d;
01923 }
01924 if ( e.hasAttributeNS( ooNS::number, "min-denominator-digits" ) )
01925 {
01926 int d = e.attributeNS( ooNS::number, "min-denominator-digits", QString::null ).toInt( &ok );
01927 if ( ok )
01928 denominator = d;
01929 }
01930
01931 for ( i = 0; i <= integer; ++i )
01932 format->append( '#' );
01933
01934 format->append( ' ' );
01935
01936 for ( i = 0; i <= numerator; ++i )
01937 format->append( '?' );
01938
01939 format->append( '/' );
01940
01941 for ( i = 0; i <= denominator; ++i )
01942 format->append( '?' );
01943 }
01944
01945
01946
01947
01948 e = e.nextSibling().toElement();
01949 }
01950
01951 if ( negRed )
01952 {
01953 QString f( *format );
01954 format->append( ";[Red]" );
01955 format->append( f );
01956 }
01957
01958 kdDebug(30518) << "*** New FormatString: " << *format << endl << endl;
01959
01960 m_formats.insert( name, format );
01961
01962 return format;
01963 }
01964
01965 void OpenCalcImport::loadFontStyle( Format * layout, QDomElement const * font ) const
01966 {
01967 if ( !font || !layout )
01968 return;
01969
01970 kdDebug(30518) << "Copy font style from the layout " << font->tagName() << ", " << font->nodeName() << endl;
01971
01972 if ( font->hasAttributeNS( ooNS::fo, "font-family" ) )
01973 layout->setTextFontFamily( font->attributeNS( ooNS::fo, "font-family", QString::null ) );
01974 if ( font->hasAttributeNS( ooNS::fo, "color" ) )
01975 layout->setTextColor( QColor( font->attributeNS( ooNS::fo, "color", QString::null ) ) );
01976 if ( font->hasAttributeNS( ooNS::fo, "font-size" ) )
01977 layout->setTextFontSize( int( KoUnit::parseValue( font->attributeNS( ooNS::fo, "font-size", QString::null ), 10 ) ) );
01978 else
01979 layout->setTextFontSize( 10 );
01980 if ( font->hasAttributeNS( ooNS::fo, "font-style" ) )
01981 {
01982 kdDebug(30518) << "italic" << endl;
01983 layout->setTextFontItalic( true );
01984 }
01985 if ( font->hasAttributeNS( ooNS::fo, "font-weight" ) )
01986 layout->setTextFontBold( true );
01987 if ( font->hasAttributeNS( ooNS::fo, "text-underline" ) || font->hasAttributeNS( ooNS::style, "text-underline" ) )
01988 layout->setTextFontUnderline( true );
01989 if ( font->hasAttributeNS( ooNS::style, "text-crossing-out" ) )
01990 layout->setTextFontStrike( true );
01991 if ( font->hasAttributeNS( ooNS::style, "font-pitch" ) )
01992 {
01993
01994 }
01995
01996
01997 }
01998
01999 void OpenCalcImport::loadBorder( Format * layout, QString const & borderDef, bPos pos ) const
02000 {
02001 if ( borderDef == "none" )
02002 return;
02003
02004 int p = borderDef.find( ' ' );
02005 if ( p < 0 )
02006 return;
02007
02008 QPen pen;
02009 QString w = borderDef.left( p );
02010 pen.setWidth( (int) KoUnit::parseValue( w ) );
02011
02012
02013 ++p;
02014 int p2 = borderDef.find( ' ', p );
02015 QString s = borderDef.mid( p, p2 - p );
02016
02017 kdDebug(30518) << "Borderstyle: " << s << endl;
02018
02019 if ( s == "solid" || s == "double" )
02020 pen.setStyle( Qt::SolidLine );
02021 else
02022 {
02023 #if 0
02024
02025 pen.setStyle( Qt::DashLine );
02026 pen.setStyle( Qt::DotLine );
02027 pen.setStyle( Qt::DashDotLine );
02028 pen.setStyle( Qt::DashDotDotLine );
02029 #endif
02030 pen.setStyle( Qt::SolidLine );
02031 }
02032
02033 ++p2;
02034 p = borderDef.find( ' ', p2 );
02035 if ( p == -1 )
02036 p = borderDef.length();
02037
02038 pen.setColor( QColor( borderDef.right( p - p2 ) ) );
02039
02040 if ( pos == Left )
02041 layout->setLeftBorderPen( pen );
02042 else if ( pos == Top )
02043 layout->setTopBorderPen( pen );
02044 else if ( pos == Right )
02045 layout->setRightBorderPen( pen );
02046 else if ( pos == Bottom )
02047 layout->setBottomBorderPen( pen );
02048 else if ( pos == Border )
02049 {
02050 layout->setLeftBorderPen( pen );
02051 layout->setTopBorderPen( pen );
02052 layout->setRightBorderPen( pen );
02053 layout->setBottomBorderPen( pen );
02054 }
02055
02056 }
02057
02058 void OpenCalcImport::loadStyleProperties( Format * layout, QDomElement const & property ) const
02059 {
02060 kdDebug(30518) << "*** Loading style properties *****" << endl;
02061
02062 if ( property.hasAttributeNS( ooNS::style, "decimal-places" ) )
02063 {
02064 bool ok = false;
02065 int p = property.attributeNS( ooNS::style, "decimal-places", QString::null ).toInt( &ok );
02066 if (ok )
02067 layout->setPrecision( p );
02068 }
02069
02070 if ( property.hasAttributeNS( ooNS::style, "font-name" ) )
02071 {
02072 QDomElement * font = m_styles[ property.attributeNS( ooNS::style, "font-name", QString::null ) ];
02073 loadFontStyle( layout, font );
02074 }
02075
02076 loadFontStyle( layout, &property );
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088 if ( property.hasAttributeNS( ooNS::style, "rotation-angle" ) )
02089 {
02090 bool ok = false;
02091 int a = property.attributeNS( ooNS::style, "rotation-angle", QString::null ).toInt( &ok );
02092 if ( ok )
02093 layout->setAngle( -a + 1 );
02094 }
02095
02096 if ( property.hasAttributeNS( ooNS::fo, "direction" ) )
02097 {
02098 layout->setVerticalText( true );
02099 }
02100 if ( property.hasAttributeNS( ooNS::fo, "text-align" ) )
02101 {
02102 QString s = property.attributeNS( ooNS::fo, "text-align", QString::null );
02103 if ( s == "center" )
02104 layout->setAlign( Format::Center );
02105 else if ( s == "end" )
02106 layout->setAlign( Format::Right );
02107 else if ( s == "start" )
02108 layout->setAlign( Format::Left );
02109 else if ( s == "justify" )
02110 layout->setAlign( Format::Center );
02111 }
02112 if ( property.hasAttributeNS( ooNS::fo, "margin-left" ) )
02113 {
02114 kdDebug(30518)<<"margin-left :"<<KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", QString::null ),0.0 )<<endl;
02115 layout->setIndent( KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", QString::null ),0.0 ) );
02116 }
02117 if ( property.hasAttributeNS( ooNS::fo, "background-color" ) )
02118 layout->setBgColor( QColor( property.attributeNS( ooNS::fo, "background-color", QString::null ) ) );
02119
02120 if ( property.hasAttributeNS( ooNS::style, "print-content" ) )
02121 {
02122 if ( property.attributeNS( ooNS::style, "print-content", QString::null ) == "false" )
02123 layout->setDontPrintText( false );
02124 }
02125 if ( property.hasAttributeNS( ooNS::style, "cell-protect" ) )
02126 {
02127 QString prot( property.attributeNS( ooNS::style, "cell-protect", QString::null ) );
02128 if ( prot == "none" )
02129 {
02130 layout->setNotProtected( true );
02131 layout->setHideFormula( false );
02132 layout->setHideAll( false );
02133 }
02134 else if ( prot == "formula-hidden" )
02135 {
02136 layout->setNotProtected( true );
02137 layout->setHideFormula( true );
02138 layout->setHideAll( false );
02139 }
02140 else if ( prot == "protected formula-hidden" )
02141 {
02142 layout->setNotProtected( false );
02143 layout->setHideFormula( true );
02144 layout->setHideAll( false );
02145 }
02146 else if ( prot == "hidden-and-protected" )
02147 {
02148 layout->setNotProtected( false );
02149 layout->setHideFormula( false );
02150 layout->setHideAll( true );
02151 }
02152 else if ( prot == "protected" )
02153 {
02154 layout->setNotProtected( false );
02155 layout->setHideFormula( false );
02156 layout->setHideAll( false );
02157 }
02158 kdDebug(30518) << "Cell " << prot << endl;
02159 }
02160
02161 if ( property.hasAttributeNS( ooNS::fo, "padding-left" ) )
02162 layout->setIndent( KoUnit::parseValue(property.attributeNS( ooNS::fo, "padding-left", QString::null ) ) );
02163
02164 if ( property.hasAttributeNS( ooNS::fo, "vertical-align" ) )
02165 {
02166 QString s = property.attributeNS( ooNS::fo, "vertical-align", QString::null );
02167 if ( s == "middle" )
02168 layout->setAlignY( Format::Middle );
02169 else if ( s == "bottom" )
02170 layout->setAlignY( Format::Bottom );
02171 else
02172 layout->setAlignY( Format::Top );
02173 }
02174 else
02175 layout->setAlignY( Format::Bottom );
02176
02177 if ( property.hasAttributeNS( ooNS::fo, "wrap-option" ) )
02178 {
02179 layout->setMultiRow( true );
02180
02181
02182
02183
02184
02185
02186 }
02187
02188 if ( property.hasAttributeNS( ooNS::fo, "border-bottom" ) )
02189 {
02190 loadBorder( layout, property.attributeNS( ooNS::fo, "border-bottom", QString::null ), Bottom );
02191
02192 }
02193
02194 if ( property.hasAttributeNS( ooNS::fo, "border-right" ) )
02195 {
02196 loadBorder( layout, property.attributeNS( ooNS::fo, "border-right", QString::null ), Right );
02197
02198 }
02199
02200 if ( property.hasAttributeNS( ooNS::fo, "border-top" ) )
02201 {
02202 loadBorder( layout, property.attributeNS( ooNS::fo, "border-top", QString::null ), Top );
02203
02204 }
02205
02206 if ( property.hasAttributeNS( ooNS::fo, "border-left" ) )
02207 {
02208 loadBorder( layout, property.attributeNS( ooNS::fo, "border-left", QString::null ), Left );
02209
02210 }
02211
02212 if ( property.hasAttributeNS( ooNS::fo, "border" ) )
02213 {
02214 loadBorder( layout, property.attributeNS( ooNS::fo, "border", QString::null ), Border );
02215
02216 }
02217 }
02218
02219 void OpenCalcImport::readInStyle( Format * layout, QDomElement const & style )
02220 {
02221 kdDebug(30518) << "** Reading Style: " << style.tagName() << "; " << style.attributeNS( ooNS::style, "name", QString::null) << endl;
02222 if ( style.localName() == "style" && style.namespaceURI()==ooNS::style)
02223 {
02224 if ( style.hasAttributeNS( ooNS::style, "parent-style-name" ) )
02225 {
02226 Format * cp
02227 = m_defaultStyles.find( style.attributeNS( ooNS::style, "parent-style-name", QString::null ) );
02228 kdDebug(30518) << "Copying layout from " << style.attributeNS( ooNS::style, "parent-style-name", QString::null ) << endl;
02229
02230 if ( cp != 0 )
02231 layout->copy( *cp );
02232 }
02233 else if ( style.hasAttributeNS( ooNS::style, "family") )
02234 {
02235 QString name = style.attribute( "style-family" ) + "default";
02236 Format * cp = m_defaultStyles.find( name );
02237
02238 kdDebug(30518) << "Copying layout from " << name << ", " << !cp << endl;
02239
02240 if ( cp != 0 )
02241 layout->copy( *cp );
02242 }
02243
02244 if ( style.hasAttributeNS( ooNS::style, "data-style-name" ) )
02245 {
02246 QString * format = m_formats[ style.attributeNS( ooNS::style, "data-style-name", QString::null ) ];
02247 FormatType formatType;
02248
02249 if ( !format )
02250 {
02251
02252 QString name( style.attributeNS( ooNS::style, "data-style-name", QString::null ) );
02253 format = loadFormat( m_styles[ name ], formatType, name );
02254 }
02255
02256 if ( format )
02257 {
02258 layout->setFormatString( *format );
02259 layout->setFormatType( formatType );
02260 }
02261
02262
02263 }
02264 }
02265
02266 QDomElement property;
02267 forEachElement( property, style )
02268 {
02269 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
02270 loadStyleProperties( layout, property );
02271
02272 kdDebug(30518) << layout->textFontFamily( 0, 0 ) << endl;
02273 }
02274 }
02275
02276 bool OpenCalcImport::createStyleMap( QDomDocument const & styles )
02277 {
02278 QDomElement content = styles.documentElement();
02279 QDomNode docStyles = KoDom::namedItemNS( content, ooNS::office, "document-styles" );
02280
02281 if ( content.hasAttributeNS( ooNS::office, "version" ) )
02282 {
02283 bool ok = true;
02284 double d = content.attributeNS( ooNS::office, "version", QString::null ).toDouble( &ok );
02285
02286 if ( ok )
02287 {
02288 kdDebug(30518) << "OpenCalc version: " << d << endl;
02289 if ( d > 1.0 )
02290 {
02291 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?") );
02292 message.arg( content.attributeNS( ooNS::office, "version", QString::null ) );
02293 if ( KMessageBox::warningYesNo( 0, message, i18n( "Unsupported document version" ) ) == KMessageBox::No )
02294 return false;
02295 }
02296 }
02297 }
02298
02299 QDomNode fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
02300
02301 if ( !fontStyles.isNull() )
02302 {
02303 kdDebug(30518) << "Starting reading in font-decl..." << endl;
02304
02305 insertStyles( fontStyles.toElement() );
02306 }
02307 else
02308 kdDebug(30518) << "No items found" << endl;
02309
02310 kdDebug(30518) << "Starting reading in auto:styles" << endl;
02311
02312 QDomNode autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
02313 if ( !autoStyles.isNull() )
02314 insertStyles( autoStyles.toElement() );
02315 else
02316 kdDebug(30518) << "No items found" << endl;
02317
02318
02319 kdDebug(30518) << "Reading in master styles" << endl;
02320
02321 QDomNode masterStyles = KoDom::namedItemNS( content, ooNS::office, "master-styles" );
02322
02323 if ( masterStyles.isNull() )
02324 {
02325 kdDebug(30518) << "Nothing found " << endl;
02326 }
02327
02328 QDomElement master = KoDom::namedItemNS( masterStyles, ooNS::style, "master-page");
02329 if ( !master.isNull() )
02330 {
02331 QString name( "pm" );
02332 name += master.attributeNS( ooNS::style, "name", QString::null );
02333 kdDebug(30518) << "Master style: '" << name << "' loaded " << endl;
02334 m_styles.insert( name, new QDomElement( master ) );
02335
02336 master = master.nextSibling().toElement();
02337 }
02338
02339
02340 kdDebug(30518) << "Starting reading in office:styles" << endl;
02341
02342 QDomNode fixedStyles = KoDom::namedItemNS( content, ooNS::office, "styles" );
02343
02344 kdDebug(30518) << "Reading in default styles" << endl;
02345
02346 QDomNode def = KoDom::namedItemNS( fixedStyles, ooNS::style, "default-style" );
02347 kdDebug()<<" def !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<def.isNull()<<endl;
02348 while ( !def.isNull() )
02349 {
02350 QDomElement e = def.toElement();
02351 kdDebug(30518) << "Style found " << e.nodeName() << ", tag: " << e.tagName() << endl;
02352
02353 if ( e.nodeName() != "style:default-style" )
02354 {
02355 def = def.nextSibling();
02356 continue;
02357 }
02358
02359 if ( !e.isNull() )
02360 {
02361 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
02362
02363 readInStyle( layout, e );
02364 kdDebug(30518) << "Default style " << e.attributeNS( ooNS::style, "family", QString::null ) << "default" << " loaded " << endl;
02365
02366 m_defaultStyles.insert( e.attributeNS( ooNS::style, "family", QString::null ) + "default", layout );
02367
02368
02369 }
02370
02371 def = def.nextSibling();
02372 }
02373
02374 QDomElement defs = KoDom::namedItemNS( fixedStyles, ooNS::style, "style" );
02375 while ( !defs.isNull() )
02376 {
02377 if ( defs.nodeName() != "style:style" )
02378 break;
02379
02380 if ( !defs.hasAttributeNS( ooNS::style, "name" ) )
02381 {
02382
02383 defs = defs.nextSibling().toElement();
02384 continue;
02385 }
02386
02387 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
02388 readInStyle( layout, defs );
02389 kdDebug(30518) << "Default style " << defs.attributeNS( ooNS::style, "name", QString::null ) << " loaded " << endl;
02390
02391 m_defaultStyles.insert( defs.attributeNS( ooNS::style, "name", QString::null ), layout );
02392
02393
02394 defs = defs.nextSibling().toElement();
02395 }
02396
02397 if ( !fixedStyles.isNull() )
02398 insertStyles( fixedStyles.toElement() );
02399
02400 kdDebug(30518) << "Starting reading in automatic styles" << endl;
02401
02402 content = m_content.documentElement();
02403 autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
02404
02405 if ( !autoStyles.isNull() )
02406 insertStyles( autoStyles.toElement() );
02407
02408 fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
02409
02410 if ( !fontStyles.isNull() )
02411 {
02412 kdDebug(30518) << "Starting reading in special font decl" << endl;
02413
02414 insertStyles( fontStyles.toElement() );
02415 }
02416
02417 kdDebug(30518) << "Styles read in." << endl;
02418
02419 return true;
02420 }
02421
02422 void OpenCalcImport::loadOasisValidation( Validity* val, const QString& validationName )
02423 {
02424 kdDebug(30518)<<"validationName:"<<validationName<<endl;
02425 QDomElement element = m_validationList[validationName];
02426 if ( element.hasAttributeNS( ooNS::table, "condition" ) )
02427 {
02428 QString valExpression = element.attributeNS( ooNS::table, "condition", QString::null );
02429 kdDebug(30518)<<" element.attribute( table:condition ) "<<valExpression<<endl;
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443 if ( valExpression.contains( "cell-content-text-length()" ) )
02444 {
02445
02446 valExpression = valExpression.remove("cell-content-text-length()" );
02447 kdDebug(30518)<<" valExpression = :"<<valExpression<<endl;
02448 val->m_restriction = Restriction::TextLength;
02449
02450 loadOasisValidationCondition( val, valExpression );
02451 }
02452
02453 else if ( valExpression.contains( "cell-content-text-length-is-between" ) )
02454 {
02455 val->m_restriction = Restriction::TextLength;
02456 val->m_cond = Conditional::Between;
02457 valExpression = valExpression.remove( "cell-content-text-length-is-between(" );
02458 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
02459 valExpression = valExpression.remove( ")" );
02460 QStringList listVal = QStringList::split( ",", valExpression );
02461 loadOasisValidationValue( val, listVal );
02462 }
02463 else if ( valExpression.contains( "cell-content-text-length-is-not-between" ) )
02464 {
02465 val->m_restriction = Restriction::TextLength;
02466 val->m_cond = Conditional::Different;
02467 valExpression = valExpression.remove( "cell-content-text-length-is-not-between(" );
02468 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
02469 valExpression = valExpression.remove( ")" );
02470 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
02471 QStringList listVal = QStringList::split( ",", valExpression );
02472 loadOasisValidationValue( val, listVal );
02473
02474 }
02475
02476 else
02477 {
02478 if (valExpression.contains( "cell-content-is-whole-number()" ) )
02479 {
02480 val->m_restriction = Restriction::Number;
02481 valExpression = valExpression.remove( "cell-content-is-whole-number() and " );
02482 }
02483 else if (valExpression.contains( "cell-content-is-decimal-number()" ) )
02484 {
02485 val->m_restriction = Restriction::Integer;
02486 valExpression = valExpression.remove( "cell-content-is-decimal-number() and " );
02487 }
02488 else if (valExpression.contains( "cell-content-is-date()" ) )
02489 {
02490 val->m_restriction = Restriction::Date;
02491 valExpression = valExpression.remove( "cell-content-is-date() and " );
02492 }
02493 else if (valExpression.contains( "cell-content-is-time()" ) )
02494 {
02495 val->m_restriction = Restriction::Time;
02496 valExpression = valExpression.remove( "cell-content-is-time() and " );
02497 }
02498 kdDebug(30518)<<"valExpression :"<<valExpression<<endl;
02499
02500 if ( valExpression.contains( "cell-content()" ) )
02501 {
02502 valExpression = valExpression.remove( "cell-content()" );
02503 loadOasisValidationCondition( val, valExpression );
02504 }
02505
02506
02507 if ( valExpression.contains( "cell-content-is-between(" ) )
02508 {
02509 valExpression = valExpression.remove( "cell-content-is-between(" );
02510 valExpression = valExpression.remove( ")" );
02511 QStringList listVal = QStringList::split( "," , valExpression );
02512 loadOasisValidationValue( val, listVal );
02513
02514 val->m_cond = Conditional::Between;
02515 }
02516 if ( valExpression.contains( "cell-content-is-not-between(" ) )
02517 {
02518 valExpression = valExpression.remove( "cell-content-is-not-between(" );
02519 valExpression = valExpression.remove( ")" );
02520 QStringList listVal = QStringList::split( ",", valExpression );
02521 loadOasisValidationValue( val, listVal );
02522 val->m_cond = Conditional::Different;
02523 }
02524 }
02525 }
02526 if ( element.hasAttributeNS( ooNS::table, "allow-empty-cell" ) )
02527 {
02528 val->allowEmptyCell = ( ( element.attributeNS( ooNS::table, "allow-empty-cell", QString::null )=="true" ) ? true : false );
02529
02530 }
02531 if ( element.hasAttributeNS( ooNS::table, "base-cell-address" ) )
02532 {
02533
02534 }
02535
02536 QDomElement help = KoDom::namedItemNS( element, ooNS::table, "help-message" );
02537 if ( !help.isNull() )
02538 {
02539 if ( help.hasAttributeNS( ooNS::table, "title" ) )
02540 val->titleInfo = help.attributeNS( ooNS::table, "title", QString::null );
02541 if ( help.hasAttributeNS( ooNS::table, "display" ) )
02542 val->displayValidationInformation = ( ( help.attributeNS( ooNS::table, "display", QString::null )=="true" ) ? true : false );
02543 QDomElement attrText = KoDom::namedItemNS( help, ooNS::text, "p" );
02544 if ( !attrText.isNull() )
02545 val->messageInfo = attrText.text();
02546 }
02547
02548 QDomElement error = KoDom::namedItemNS( element, ooNS::table, "error-message" );
02549 if ( !error.isNull() )
02550 {
02551 if ( error.hasAttributeNS( ooNS::table, "title" ) )
02552 val->title = error.attributeNS( ooNS::table, "title", QString::null );
02553 if ( error.hasAttributeNS( ooNS::table, "message-type" ) )
02554 {
02555 QString str = error.attributeNS( ooNS::table, "message-type", QString::null );
02556 if ( str == "warning" )
02557 val->m_action = Action::Warning;
02558 else if ( str == "information" )
02559 val->m_action = Action::Information;
02560 else if ( str == "stop" )
02561 val->m_action = Action::Stop;
02562 else
02563 kdDebug(30518)<<"validation : message type unknown :"<<str<<endl;
02564 }
02565
02566 if ( error.hasAttributeNS( ooNS::table, "display" ) )
02567 {
02568 kdDebug(30518)<<" display message :"<<error.attributeNS( ooNS::table, "display", QString::null )<<endl;
02569 val->displayMessage = (error.attributeNS( ooNS::table, "display", QString::null )=="true");
02570 }
02571 QDomElement attrText = KoDom::namedItemNS( error, ooNS::text, "p" );
02572 if ( !attrText.isNull() )
02573 val->message = attrText.text();
02574 }
02575 }
02576
02577 void OpenCalcImport::loadOasisValidationValue( Validity* val, const QStringList &listVal )
02578 {
02579 bool ok = false;
02580 kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
02581
02582 if ( val->m_restriction == Restriction::Date )
02583 {
02584 val->dateMin = QDate::fromString( listVal[0] );
02585 val->dateMax = QDate::fromString( listVal[1] );
02586 }
02587 else if ( val->m_restriction == Restriction::Time )
02588 {
02589 val->timeMin = QTime::fromString( listVal[0] );
02590 val->timeMax = QTime::fromString( listVal[1] );
02591 }
02592 else
02593 {
02594 val->valMin = listVal[0].toDouble(&ok);
02595 if ( !ok )
02596 {
02597 val->valMin = listVal[0].toInt(&ok);
02598 if ( !ok )
02599 kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
02600
02601 #if 0
02602 if ( !ok )
02603 val->valMin = listVal[0];
02604 #endif
02605 }
02606 ok=false;
02607 val->valMax = listVal[1].toDouble(&ok);
02608 if ( !ok )
02609 {
02610 val->valMax = listVal[1].toInt(&ok);
02611 if ( !ok )
02612 kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
02613
02614 #if 0
02615 if ( !ok )
02616 val->valMax = listVal[1];
02617 #endif
02618 }
02619 }
02620 }
02621
02622
02623 void OpenCalcImport::loadOasisValidationCondition( Validity* val,QString &valExpression )
02624 {
02625 QString value;
02626 if (valExpression.contains( "<=" ) )
02627 {
02628 value = valExpression.remove( "<=" );
02629 val->m_cond = Conditional::InferiorEqual;
02630 }
02631 else if (valExpression.contains( ">=" ) )
02632 {
02633 value = valExpression.remove( ">=" );
02634 val->m_cond = Conditional::SuperiorEqual;
02635 }
02636 else if (valExpression.contains( "!=" ) )
02637 {
02638
02639 value = valExpression.remove( "!=" );
02640 val->m_cond = Conditional::DifferentTo;
02641 }
02642 else if ( valExpression.contains( "<" ) )
02643 {
02644 value = valExpression.remove( "<" );
02645 val->m_cond = Conditional::Inferior;
02646 }
02647 else if(valExpression.contains( ">" ) )
02648 {
02649 value = valExpression.remove( ">" );
02650 val->m_cond = Conditional::Superior;
02651 }
02652 else if (valExpression.contains( "=" ) )
02653 {
02654 value = valExpression.remove( "=" );
02655 val->m_cond = Conditional::Equal;
02656 }
02657 else
02658 kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
02659 kdDebug(30518)<<" value :"<<value<<endl;
02660 if ( val->m_restriction == Restriction::Date )
02661 {
02662 val->dateMin = QDate::fromString( value );
02663 }
02664 else if ( val->m_restriction == Restriction::Date )
02665 {
02666 val->timeMin = QTime::fromString( value );
02667 }
02668 else
02669 {
02670 bool ok = false;
02671 val->valMin = value.toDouble(&ok);
02672 if ( !ok )
02673 {
02674 val->valMin = value.toInt(&ok);
02675 if ( !ok )
02676 kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
02677
02678 #if 0
02679 if ( !ok )
02680 val->valMin = value;
02681 #endif
02682 }
02683 }
02684 }
02685
02686
02687 int OpenCalcImport::readMetaData()
02688 {
02689 int result = 5;
02690 KoDocumentInfo * docInfo = m_doc->documentInfo();
02691 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(docInfo->page( "about" ));
02692 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>(docInfo->page( "author" ));
02693
02694 QDomNode meta = KoDom::namedItemNS( m_meta, ooNS::office, "document-meta" );
02695 QDomNode office = KoDom::namedItemNS( meta, ooNS::office, "meta" );
02696
02697 if ( office.isNull() )
02698 return 2;
02699
02700 QDomElement e = KoDom::namedItemNS( office, ooNS::dc, "creator" );
02701 if ( !e.isNull() && !e.text().isEmpty() )
02702 authorPage->setFullName( e.text() );
02703
02704 e = KoDom::namedItemNS( office, ooNS::dc, "title" );
02705 if ( !e.isNull() && !e.text().isEmpty() )
02706 aboutPage->setTitle( e.text() );
02707
02708 e = KoDom::namedItemNS( office, ooNS::dc, "description" );
02709 if ( !e.isNull() && !e.text().isEmpty() )
02710 aboutPage->setAbstract( e.text() );
02711
02712 e = KoDom::namedItemNS( office, ooNS::dc, "subject" );
02713 if ( !e.isNull() && !e.text().isEmpty() )
02714 aboutPage->setSubject( e.text() );
02715
02716 e= KoDom::namedItemNS( office, ooNS::meta, "keywords" );
02717 if ( !e.isNull() )
02718 {
02719 e = KoDom::namedItemNS( e, ooNS::meta, "keyword" );
02720 if ( !e.isNull() && !e.text().isEmpty() )
02721 aboutPage->setKeywords( e.text() );
02722 }
02723
02724 e = KoDom::namedItemNS( office, ooNS::meta, "document-statistic" );
02725 if ( !e.isNull() && e.hasAttributeNS( ooNS::meta, "table-count" ) )
02726 {
02727 bool ok = false;
02728 result = e.attributeNS( ooNS::meta, "table-count", QString::null ).toInt( &ok );
02729 if ( !ok )
02730 result = 5;
02731 }
02732
02733 m_meta.clear();
02734
02735 return result;
02736 }
02737
02738 KoFilter::ConversionStatus OpenCalcImport::convert( QCString const & from, QCString const & to )
02739 {
02740 kdDebug(30518) << "Entering OpenCalc Import filter: " << from << " - " << to << endl;
02741
02742 KoDocument * document = m_chain->outputDocument();
02743 if ( !document )
02744 return KoFilter::StupidError;
02745
02746 if ( !::qt_cast<const KSpread::Doc *>( document ) )
02747 {
02748 kdWarning(30518) << "document isn't a KSpread::Doc but a " << document->className() << endl;
02749 return KoFilter::NotImplemented;
02750 }
02751
02752 if ( ( from != "application/vnd.sun.xml.calc" && from != "application/vnd.sun.xml.calc.template") || to != "application/x-kspread" )
02753 {
02754 kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl;
02755 return KoFilter::NotImplemented;
02756 }
02757
02758 m_doc = ( Doc * ) document;
02759
02760 if ( m_doc->mimeType() != "application/x-kspread" )
02761 {
02762 kdWarning(30518) << "Invalid document mimetype " << m_doc->mimeType() << endl;
02763 return KoFilter::NotImplemented;
02764 }
02765
02766 kdDebug(30518) << "Opening file " << endl;
02767
02768 KoFilter::ConversionStatus preStatus = openFile();
02769
02770 if ( preStatus != KoFilter::OK )
02771 return preStatus;
02772
02773 emit sigProgress( 13 );
02774 int tables = readMetaData();
02775
02776 emit sigProgress( 15 );
02777
02778 if ( !parseBody( tables ) )
02779 return KoFilter::StupidError;
02780
02781 emit sigProgress( 100 );
02782 return KoFilter::OK;
02783 }
02784
02785 KoFilter::ConversionStatus OpenCalcImport::openFile()
02786 {
02787 KoStore * store = KoStore::createStore( m_chain->inputFile(), KoStore::Read);
02788
02789 kdDebug(30518) << "Store created" << endl;
02790
02791 if ( !store )
02792 {
02793 kdWarning(30518) << "Couldn't open the requested file." << endl;
02794 return KoFilter::FileNotFound;
02795 }
02796
02797 kdDebug(30518) << "Trying to open content.xml" << endl;
02798 QString messageError;
02799 loadAndParse( m_content, "content.xml", store);
02800 kdDebug(30518) << "Opened" << endl;
02801
02802 QDomDocument styles;
02803 kdDebug(30518) << "file content.xml loaded " << endl;
02804
02805 loadAndParse( styles, "styles.xml", store);
02806
02807 loadAndParse( m_meta, "meta.xml", store);
02808 loadAndParse( m_settings, "settings.xml", store);
02809
02810 delete store;
02811
02812 emit sigProgress( 10 );
02813
02814 if ( !createStyleMap( styles ) )
02815 return KoFilter::UserCancelled;
02816
02817 return KoFilter::OK;
02818 }
02819
02820 KoFilter::ConversionStatus OpenCalcImport::loadAndParse( QDomDocument& doc, const QString& fileName,KoStore *m_store )
02821 {
02822 return OoUtils::loadAndParse( fileName, doc, m_store);
02823 }
02824
02825 #include "opencalcimport.moc"
02826