filters

opencalcimport.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002 Norbert Andres <nandres@web.de>
3 Copyright (C) 2004 - 2005 Laurent Montel <montel@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include <float.h>
22#include <math.h>
23
24#include <tqcolor.h>
25#include <tqfile.h>
26#include <tqfont.h>
27#include <tqpen.h>
28#include <tqxml.h>
29
30#include "opencalcimport.h"
31
32#include <kdebug.h>
33#include <KoDocumentInfo.h>
34#include <kgenericfactory.h>
35#include <tdemessagebox.h>
36#include <kmdcodec.h>
37#include <KoFilterChain.h>
38#include <KoGlobal.h>
39#include <KoUnit.h>
40#include <KoStyleStack.h>
41#include <KoDom.h>
42#include <ooutils.h>
43
44#include <kspread_cell.h>
45#include <kspread_condition.h>
46#include <kspread_doc.h>
47#include <kspread_global.h>
48#include <kspread_map.h>
49#include <kspread_sheet.h>
50#include <kspread_sheetprint.h>
51#include <kspread_style.h>
52#include <kspread_style_manager.h>
53#include <kspread_util.h>
54#include <kspread_value.h>
55
56#define SECSPERDAY (24 * 60 * 60)
57
58using namespace KSpread;
59
60class OpenCalcImportFactory : KGenericFactory<OpenCalcImport, KoFilter>
61{
62public:
63 OpenCalcImportFactory(void) : KGenericFactory<OpenCalcImport, KoFilter> ("kspreadopencalcimport")
64 {}
65protected:
66 virtual void setupTranslations( void )
67 {
68 TDEGlobal::locale()->insertCatalogue( "kofficefilters" );
69 }
70};
71
72K_EXPORT_COMPONENT_FACTORY( libopencalcimport, OpenCalcImportFactory() )
73
74OpenCalcImport::OpenCalcPoint::OpenCalcPoint( TQString const & str )
75 : isRange( false )
76{
77 bool inQuote = false;
78
79 int l = str.length();
80 int colonPos = -1;
81 TQString range;
82
83 // replace '.' with '!'
84 for ( int i = 0; i < l; ++i )
85 {
86 if ( str[i] == '$' )
87 continue;
88 if ( str[i] == '\'' )
89 {
90 inQuote = !inQuote;
91 }
92 else if ( str[i] == '.' )
93 {
94 if ( !inQuote )
95 {
96 if ( i != 0 && i != (colonPos + 1) ) // no empty table names
97 range += '!';
98 }
99 else
100 range += '.';
101 }
102 else if ( str[i] == ':' )
103 {
104 if ( !inQuote )
105 {
106 isRange = true;
107 colonPos = i;
108 }
109 range += ':';
110 }
111 else
112 range += str[i];
113 }
114
115 translation = range;
116
117 if ( isRange )
118 {
119 KSpread::Range newRange( range );
120 table = newRange.sheetName();
121 topLeft = newRange.range().topLeft();
122 botRight = newRange.range().bottomRight();
123 }
124 else
125 {
126 Point newPoint( range );
127 table = newPoint.sheetName();
128 topLeft = newPoint.pos();
129 botRight = newPoint.pos();
130 }
131}
132
133
134OpenCalcImport::OpenCalcImport( KoFilter *, const char *, const TQStringList & )
135 : KoFilter(),
136 m_styles( 17, true ),
137 m_defaultStyles( 17, true ),
138 m_formats( 17, true )
139{
140 m_styles.setAutoDelete( true );
141 m_defaultStyles.setAutoDelete( true );
142 m_formats.setAutoDelete( true );
143}
144
145OpenCalcImport::~OpenCalcImport()
146{
147}
148
149double timeToNum( int h, int m, int s )
150{
151 int secs = h * 3600 + m * 60 + s;
152 return (double) secs / (double) SECSPERDAY;
153}
154
155bool OpenCalcImport::readRowFormat( TQDomElement & rowNode, TQDomElement * rowStyle,
156 Sheet * table, int & row, int & number,
157 bool isLast )
158{
159 if ( rowNode.isNull() )
160 return false;
161
162 TQDomNode node;
163 if ( rowStyle )
164 {
165 node = rowStyle->firstChild();
166 kdDebug(30518) << "RowStyle: " << rowStyle << ", " << rowStyle->tagName() << endl;
167 }
168
169 double height = -1.0;
170 bool insertPageBreak = false;
171 Format layout( table, table->doc()->styleManager()->defaultStyle() );
172
173 while( !node.isNull() )
174 {
175 TQDomElement property = node.toElement();
176
177 kdDebug(30518) << "Row: Child exists: " << property.tagName() << endl;
178 if ( !property.isNull() && property.localName() == "properties" && property.namespaceURI() == ooNS::style )
179 {
180 if ( property.hasAttributeNS( ooNS::style, "row-height" ) )
181 {
182 height = KoUnit::parseValue( property.attributeNS( ooNS::style, "row-height", TQString() ) , -1 );
183 }
184
185 if ( property.hasAttributeNS( ooNS::fo, "break-before" ) )
186 {
187 if ( property.attributeNS( ooNS::fo, "break-before", TQString() ) == "page" )
188 {
189 insertPageBreak = true;
190 }
191 }
192
193 loadStyleProperties( &layout, property );
194 }
195
196 node = node.nextSibling();
197 }
198
199 if ( rowNode.hasAttributeNS( ooNS::table, "number-rows-repeated" ) )
200 {
201 bool ok = true;
202 int n = rowNode.attributeNS( ooNS::table, "number-rows-repeated", TQString() ).toInt( &ok );
203 if ( ok )
204 number = n;
205 kdDebug(30518) << "Row repeated: " << number << endl;
206 }
207
208 if ( isLast )
209 {
210 if ( number > 30 )
211 number = 30;
212 }
213 else
214 {
215 if ( number > 256 )
216 number = 256;
217 }
218
219 for ( int i = 0; i < number; ++i )
220 {
221 RowFormat * rowL = table->nonDefaultRowFormat( row );
222 rowL->copy( layout );
223
224 if ( height != -1 )
225 {
226 kdDebug(30518) << "Setting row height to " << height << endl;
227 rowL->setHeight( int( height ) );
228 }
229
230 // if ( insertPageBreak ) TODO:
231 // rowL->setPageBreak( true )
232
233 // kdDebug(30518) << "Added RowFormat: " << row << endl;
234 ++row;
235 }
236
237 return true;
238}
239
240TQString OpenCalcImport::translatePar( TQString & par ) const
241{
242 OpenCalcPoint point( par );
243 kdDebug(30518) << " Parameter: " << par << ", Translation: " << point.translation << endl;
244
245 return point.translation;
246}
247
248void OpenCalcImport::checkForNamedAreas( TQString & formula ) const
249{
250 int l = formula.length();
251 int i = 0;
252 TQString word;
253 int start = 0;
254 while ( i < l )
255 {
256 if ( formula[i].isLetterOrNumber() )
257 {
258 word += formula[i];
259 ++i;
260 continue;
261 }
262 if ( word.length() > 0 )
263 {
264 if ( m_namedAreas.find( word ) != m_namedAreas.end() )
265 {
266 formula = formula.replace( start, word.length(), "'" + word + "'" );
267 l = formula.length();
268 ++i;
269 kdDebug(30518) << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
270 }
271 }
272
273 ++i;
274 word = "";
275 start = i;
276 }
277 if ( word.length() > 0 )
278 {
279 if ( m_namedAreas.find( word ) != m_namedAreas.end() )
280 {
281 formula = formula.replace( start, word.length(), "'" + word + "'" );
282 l = formula.length();
283 ++i;
284 kdDebug(30518) << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
285 }
286 }
287}
288
289void OpenCalcImport::convertFormula( TQString & text, TQString const & f ) const
290{
291 kdDebug(30518) << "Parsing formula: " << f << endl;
292
293 TQString formula;
294 TQString parameter;
295
296 int l = f.length();
297 int p = 0;
298
299 while ( p < l )
300 {
301 if ( f[p] == '(' || f[p] == '[' )
302 {
303 break;
304 }
305
306 formula += f[p];
307 ++p;
308 }
309
310 if ( parameter.isEmpty() )
311 {
312 checkForNamedAreas( formula );
313 }
314
315 kdDebug(30518) << "Formula: " << formula << ", Parameter: " << parameter << ", P: " << p << endl;
316
317
318 // replace formula names here
319 if ( formula == "=MULTIPLE.OPERATIONS" )
320 formula = "=MULTIPLEOPERATIONS";
321
322 TQString par;
323 bool isPar = false;
324 bool inQuote = false;
325
326 while ( p < l )
327 {
328 if ( f[p] == '"' )
329 {
330 inQuote = !inQuote;
331 parameter += '"';
332 }
333 else if ( f[p] == '[' )
334 {
335 if ( !inQuote )
336 isPar = true;
337 else
338 parameter += '[';
339 }
340 else if ( f[p] == ']' )
341 {
342 if ( inQuote )
343 {
344 parameter += ']';
345 continue;
346 }
347
348 isPar = false;
349 parameter += translatePar( par );
350 par = "";
351 }
352 else if ( isPar )
353 {
354 par += f[p];
355 }
356 else if ( f[p] == '=' ) // TODO: check if StarCalc has a '==' sometimes
357 {
358 if ( inQuote )
359 parameter += '=';
360 else
361 parameter += "==";
362 }
363 else if ( f[p] == ')' )
364 {
365 if ( !inQuote )
366 parameter += ")";
367 }
368 else
369 parameter += f[p];
370
371 ++p;
372 if ( p == l )
373 checkForNamedAreas( parameter );
374 }
375
376 text = formula + parameter;
377 kdDebug(30518) << "New formula: " << text << endl;
378}
379
380bool OpenCalcImport::readCells( TQDomElement & rowNode, Sheet * table, int row, int & columns )
381{
382 bool ok = true;
383 int spanC = 1;
384 int spanR = 1;
385 //Cell* defCell = table->defaultCell();
386
387 TQDomNode cellNode = KoDom::namedItemNS( rowNode, ooNS::table, "table-cell" );
388
389 while ( !cellNode.isNull() )
390 {
391 spanR = 1; spanC = 1;
392
393 TQDomElement e = cellNode.toElement();
394 if ( e.isNull() )
395 {
396 ++columns;
397
398 cellNode = cellNode.nextSibling();
399 continue;
400 }
401
402 Cell* cell = 0;
403
404 kdDebug(30518) << " Cell: " << columns << ", " << row << endl;
405
406 // ="3" table:number-rows-spanned="1"
407 if ( e.hasAttributeNS( ooNS::table, "number-columns-spanned" ) )
408 {
409 int span = e.attributeNS( ooNS::table, "number-columns-spanned", TQString() ).toInt( &ok );
410 if ( ok )
411 spanC = span;
412 }
413 if ( e.hasAttributeNS( ooNS::table, "number-rows-spanned" ) )
414 {
415 int span = e.attributeNS( ooNS::table, "number-rows-spanned", TQString() ).toInt( &ok );
416 if ( ok )
417 spanR = span;
418 }
419
420 TQString text;
421 TQDomElement textP = KoDom::namedItemNS( e, ooNS::text, "p" );
422 if ( !textP.isNull() )
423 {
424 TQDomElement subText = textP.firstChild().toElement(); // ## wrong
425 if ( !subText.isNull() )
426 {
427 // something in <text:p>, e.g. links
428 text = subText.text();
429
430 if ( subText.hasAttributeNS( ooNS::xlink, "href" ) )
431 {
432 TQString link = subText.attributeNS( ooNS::xlink, "href", TQString() );
433 if ( link[0]=='#' )
434 link=link.remove( 0, 1 );
435 if ( !cell )
436 cell = table->nonDefaultCell( columns, row );
437 cell->setLink( link );
438 }
439 }
440 else
441 text = textP.text(); // our text, could contain formating for value or result of formula
442 }
443 TQDomElement annotation = KoDom::namedItemNS( e, ooNS::office, "annotation" );
444 if ( !annotation.isNull() )
445 {
446 TQString comment;
447 TQDomNode node = annotation.firstChild();
448 while( !node.isNull() )
449 {
450 TQDomElement commentElement = node.toElement();
451 if( !commentElement.isNull() )
452 if ( commentElement.localName() == "p" && e.namespaceURI()==ooNS::text)
453 {
454 if( !comment.isEmpty() ) comment.append( '\n' );
455 comment.append( commentElement.text() );
456 }
457
458 node = node.nextSibling();
459 }
460
461 if( !comment.isEmpty() )
462 {
463 if ( !cell )
464 cell = table->nonDefaultCell( columns, row );
465 kdDebug(30518)<<" columns :"<<columns<<" row :"<<row<<endl;
466 cell->format()->setComment( comment );
467 }
468 }
469
470 kdDebug(30518) << "Contains: " << text << endl;
471 bool isFormula = false;
472
473 if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
474 {
475 if ( !cell )
476 cell = table->nonDefaultCell( columns, row );
477
478 TQString psName( "Default" );
479 if ( e.hasAttributeNS( ooNS::style, "parent-style-name" ) )
480 psName = e.attributeNS( ooNS::style, "parent-style-name", TQString() );
481
482 kdDebug(30518) << "Default style: " << psName << endl;
483 Format * layout = m_defaultStyles[psName];
484
485 if ( layout )
486 cell->format()->copy( *layout );
487
488 TQDomElement * st = 0;
489 if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
490 {
491 kdDebug(30518) << "Style: " << e.attributeNS( ooNS::table, "style-name", TQString() ) << endl;
492 st = m_styles[ e.attributeNS( ooNS::table, "style-name", TQString() ) ];
493 }
494 if ( st )
495 {
496 kdDebug(30518) << "Style: adapting " << endl;
497 TQDomNode node = st->firstChild();
498 bool foundValidation = false;
499 while( !node.isNull() )
500 {
501 TQDomElement property = node.toElement();
502 if ( !property.isNull() )
503 {
504 kdDebug(30518)<<"property.tagName() :"<<property.tagName()<<endl;
505 if ( property.localName()=="map" && property.namespaceURI() == ooNS::style && !foundValidation)
506 {
507 loadCondition( cell, property );
508 foundValidation = true;
509 }
510 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
511 {
512 loadStyleProperties( cell->format(), property );
513 if ( cell->format()->getAngle( columns, row ) != 0 )
514 {
515 TQFontMetrics fm( cell->format()->textFont( columns, row ) );
516 int tmpAngle = cell->format()->getAngle( columns, row );
517 int textHeight = static_cast<int>( cos( tmpAngle * M_PI / 180 )
518 * ( fm.ascent() + fm.descent() )
519 + abs ( ( int )( fm.width( cell->strOutText() )
520 * sin( tmpAngle * M_PI / 180 ) ) ) );
521 /*
522 int textWidth = static_cast<int>( abs ( ( int ) ( sin( tmpAngle * M_PI / 180 )
523 * ( fm.ascent() + fm.descent() ) ) )
524 + fm.width( cell->strOutText() )
525 * cos( tmpAngle * M_PI / 180 ) );
526 */
527 kdDebug(30518) << "Rotation: height: " << textHeight << endl;
528
529 RowFormat * l = table->rowFormat( row );
530 if ( l->height() < textHeight )
531 {
532 if ( l->isDefault() )
533 l = table->nonDefaultRowFormat( row );
534
535 l->setHeight( textHeight + 2 );
536 }
537 }
538 }
539 }
540 node = node.nextSibling();
541 }
542 }
543 }
544 else
545 {
546 if ( !cell )
547 cell = table->nonDefaultCell( columns, row );
548
549 TQString psName( "Default" );
550 kdDebug(30518) << "Default style: " << psName << endl;
551 Format * layout = m_defaultStyles[psName];
552
553 if ( layout )
554 cell->format()->copy( *layout );
555 }
556 if ( e.hasAttributeNS( ooNS::table, "formula" ) )
557 {
558 isFormula = true;
559 TQString formula;
560 convertFormula( formula, e.attributeNS( ooNS::table, "formula", TQString() ) );
561
562 if ( !cell )
563 cell = table->nonDefaultCell( columns, row );
564 cell->setCellText( formula );
565 }
566 if ( e.hasAttributeNS( ooNS::table, "validation-name" ) )
567 {
568 kdDebug(30518)<<" Celle has a validation :"<<e.attributeNS( ooNS::table, "validation-name", TQString() )<<endl;
569 loadOasisValidation( cell->getValidity(), e.attributeNS( ooNS::table, "validation-name", TQString() ) );
570 }
571 if ( e.hasAttributeNS( ooNS::table, "value-type" ) )
572 {
573 if ( !cell )
574 cell = table->nonDefaultCell( columns, row );
575
576 cell->setCellText( text );
577
578 TQString value = e.attributeNS( ooNS::table, "value", TQString() );
579 TQString type = e.attributeNS( ooNS::table, "value-type", TQString() );
580
581 kdDebug(30518) << "Value: " << value << ", type: " << type << endl;
582
583 bool ok = false;
584 double dv = 0.0;
585
586 if ( ( type == "float" ) || ( type == "currency" ) )
587 {
588 dv = value.toDouble( &ok );
589 if ( ok )
590 {
591 if ( !isFormula )
592 cell->setValue( dv );
593
594 if ( type == "currency" )
595 {
596 cell->format()->setCurrency( 1, e.attributeNS( ooNS::table, "currency", TQString() ) );
597 cell->format()->setFormatType( Money_format );
598 }
599 }
600 }
601 else
602 if ( type == "percentage" )
603 {
604 dv = value.toDouble( &ok );
605 if ( ok )
606 {
607 if ( !isFormula )
608 cell->setValue( dv );
609 //TODO fixme
610 //cell->setFactor( 100 );
611 // TODO: replace with custom...
612 cell->format()->setFormatType( Percentage_format );
613 }
614 }
615 else if ( type == "boolean" )
616 {
617 if ( value.isEmpty() )
618 value = e.attributeNS( ooNS::table, "boolean-value", TQString() );
619
620 kdDebug(30518) << "Type: boolean" << endl;
621 if ( value == "true" )
622 cell->setValue( true );
623 else
624 cell->setValue( false );
625 ok = true;
626 cell->format()->setFormatType( Custom_format );
627 }
628 else if ( type == "date" )
629 {
630 if ( value.isEmpty() )
631 value = e.attributeNS( ooNS::table, "date-value", TQString() );
632 kdDebug(30518) << "Type: date, value: " << value << endl;
633
634 // "1980-10-15"
635 int year=0, month=0, day=0;
636 ok = false;
637
638 int p1 = value.find( '-' );
639 if ( p1 > 0 )
640 year = value.left( p1 ).toInt( &ok );
641
642 kdDebug(30518) << "year: " << value.left( p1 ) << endl;
643
644 int p2 = value.find( '-', ++p1 );
645
646 if ( ok )
647 month = value.mid( p1, p2 - p1 ).toInt( &ok );
648
649 kdDebug(30518) << "month: " << value.mid( p1, p2 - p1 ) << endl;
650
651 if ( ok )
652 day = value.right( value.length() - p2 - 1 ).toInt( &ok );
653
654 kdDebug(30518) << "day: " << value.right( value.length() - p2 ) << endl;
655
656 if ( ok )
657 {
658 TQDateTime dt( TQDate( year, month, day ) );
659 // KSpreadValue kval( dt );
660 // cell->setValue( kval );
661 cell->setValue( TQDate( year, month, day ) );
662 kdDebug(30518) << "Set TQDate: " << year << " - " << month << " - " << day << endl;
663 }
664 }
665 else if ( type == "time" )
666 {
667 if ( value.isEmpty() )
668 value = e.attributeNS( ooNS::table, "time-value", TQString() );
669
670 kdDebug(30518) << "Type: time: " << value << endl;
671 // "PT15H10M12S"
672 int hours=0, minutes=0, seconds=0;
673 int l = value.length();
674 TQString num;
675
676 for ( int i = 0; i < l; ++i )
677 {
678 if ( value[i].isNumber() )
679 {
680 num += value[i];
681 continue;
682 }
683 else if ( value[i] == 'H' )
684 hours = num.toInt( &ok );
685 else if ( value[i] == 'M' )
686 minutes = num.toInt( &ok );
687 else if ( value[i] == 'S' )
688 seconds = num.toInt( &ok );
689 else
690 continue;
691
692 kdDebug(30518) << "Num: " << num << endl;
693
694 num = "";
695 if ( !ok )
696 break;
697 }
698
699 kdDebug(30518) << "Hours: " << hours << ", " << minutes << ", " << seconds << endl;
700
701 if ( ok )
702 {
703 // KSpreadValue kval( timeToNum( hours, minutes, seconds ) );
704 // cell->setValue( kval );
705 cell->setValue( TQTime( hours % 24, minutes, seconds ) );
706 cell->format()->setFormatType( Custom_format );
707 }
708 }
709
710
711 if ( !ok ) // just in case we couldn't set the value directly
712 cell->setCellText( text );
713 }
714 else if ( !text.isEmpty() )
715 {
716 if ( !cell )
717 cell = table->nonDefaultCell( columns, row );
718 cell->setCellText( text );
719 }
720
721 if ( spanR > 1 || spanC > 1 )
722 {
723 if ( !cell )
724 cell = table->nonDefaultCell( columns, row );
725 cell->mergeCells( columns, row, spanC - 1, spanR - 1 );
726 }
727
728 cellNode = cellNode.nextSibling();
729
730 if ( e.hasAttributeNS( ooNS::table, "number-columns-repeated" ) )
731 {
732 // copy cell from left
733 bool ok = false;
734 int number = e.attributeNS( ooNS::table, "number-columns-repeated", TQString() ).toInt( &ok );
735 Cell* cellDest = 0;
736
737 // don't repeat more than 10 if it is the last cell and empty
738 if ( !ok || cellNode.isNull() )
739 {
740 if ( number > 10 )
741 number = 10;
742 }
743
744 for ( int i = 1; i < number; ++i )
745 {
746 ++columns;
747
748 if ( cell )
749 {
750 cellDest = table->nonDefaultCell( columns, row );
751 cellDest->copyAll( cell );
752 }
753 }
754 }
755
756 ++columns;
757 }
758
759 return true;
760}
761
762
763void OpenCalcImport::loadCondition( Cell*cell,const TQDomElement &property )
764{
765 kdDebug(30518)<<"void OpenCalcImport::loadCondition( Cell*cell,const TQDomElement &property )*******\n";
766 loadOasisCondition( cell, property );
767}
768
769void OpenCalcImport::loadOasisCondition(Cell*cell,const TQDomElement &property )
770{
771 TQDomElement elementItem( property );
772 StyleManager * manager = cell->sheet()->doc()->styleManager();
773
774 TQValueList<Conditional> cond;
775 while ( !elementItem.isNull() )
776 {
777 kdDebug(30518)<<"elementItem.tagName() :"<<elementItem.tagName()<<endl;
778
779 if ( elementItem.localName()== "map" && property.namespaceURI() == ooNS::style )
780 {
781 bool ok = true;
782 kdDebug(30518)<<"elementItem.attribute(style:condition ) :"<<elementItem.attributeNS( ooNS::style, "condition", TQString() )<<endl;
783 Conditional newCondition;
784 loadOasisConditionValue( elementItem.attributeNS( ooNS::style, "condition", TQString() ), newCondition );
785 if ( elementItem.hasAttributeNS( ooNS::style, "apply-style-name" ) )
786 {
787 kdDebug(30518)<<"elementItem.attribute( style:apply-style-name ) :"<<elementItem.attributeNS( ooNS::style, "apply-style-name", TQString() )<<endl;
788 newCondition.styleName = new TQString( elementItem.attributeNS( ooNS::style, "apply-style-name", TQString() ) );
789 newCondition.style = manager->style( *newCondition.styleName );
790 if ( !newCondition.style )
791 ok = false;
792 else
793 ok = true;
794 }
795
796 if ( ok )
797 cond.append( newCondition );
798 else
799 kdDebug(30518) << "Error loading condition " << elementItem.nodeName()<< endl;
800 }
801 elementItem = elementItem.nextSibling().toElement();
802 }
803 if ( !cond.isEmpty() )
804 cell->setConditionList( cond );
805}
806
807void OpenCalcImport::loadOasisConditionValue( const TQString &styleCondition, Conditional &newCondition )
808{
809 TQString val( styleCondition );
810 if ( val.contains( "cell-content()" ) )
811 {
812 val = val.remove( "cell-content()" );
813 loadOasisCondition( val,newCondition );
814 }
815 //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value)
816 //for the moment we support just int/double value, not text/date/time :(
817 if ( val.contains( "cell-content-is-between(" ) )
818 {
819 val = val.remove( "cell-content-is-between(" );
820 val = val.remove( ")" );
821 TQStringList listVal = TQStringList::split( "," , val );
822 loadOasisValidationValue( listVal, newCondition );
823 newCondition.cond = Conditional::Between;
824 }
825 if ( val.contains( "cell-content-is-not-between(" ) )
826 {
827 val = val.remove( "cell-content-is-not-between(" );
828 val = val.remove( ")" );
829 TQStringList listVal = TQStringList::split( ",", val );
830 loadOasisValidationValue( listVal,newCondition );
831 newCondition.cond = Conditional::Different;
832 }
833
834}
835
836
837void OpenCalcImport::loadOasisCondition( TQString &valExpression, Conditional &newCondition )
838{
839 TQString value;
840 if (valExpression.find( "<=" )==0 )
841 {
842 value = valExpression.remove( 0,2 );
843 newCondition.cond = Conditional::InferiorEqual;
844 }
845 else if (valExpression.find( ">=" )==0 )
846 {
847 value = valExpression.remove( 0,2 );
848 newCondition.cond = Conditional::SuperiorEqual;
849 }
850 else if (valExpression.find( "!=" )==0 )
851 {
852 //add Differentto attribute
853 value = valExpression.remove( 0,2 );
854 newCondition.cond = Conditional::DifferentTo;
855 }
856 else if ( valExpression.find( "<" )==0 )
857 {
858 value = valExpression.remove( 0,1 );
859 newCondition.cond = Conditional::Inferior;
860 }
861 else if(valExpression.find( ">" )==0 )
862 {
863 value = valExpression.remove( 0,1 );
864 newCondition.cond = Conditional::Superior;
865 }
866 else if (valExpression.find( "=" )==0 )
867 {
868 value = valExpression.remove( 0,1 );
869 newCondition.cond = Conditional::Equal;
870 }
871 else
872 kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
873 kdDebug(30518)<<" value :"<<value<<endl;
874 bool ok = false;
875 newCondition.val1 = value.toDouble(&ok);
876 if ( !ok )
877 {
878 newCondition.val1 = value.toInt(&ok);
879 if ( !ok )
880 {
881 newCondition.strVal1 = new TQString( value );
882 kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
883 }
884
885 }
886}
887
888
889void OpenCalcImport::loadOasisValidationValue( const TQStringList &listVal, Conditional &newCondition )
890{
891 bool ok = false;
892 kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
893
894 newCondition.val1 = listVal[0].toDouble(&ok);
895 if ( !ok )
896 {
897 newCondition.val1 = listVal[0].toInt(&ok);
898 if ( !ok )
899 {
900 newCondition.strVal1 = new TQString( listVal[0] );
901 kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
902 }
903 }
904 ok=false;
905 newCondition.val2 = listVal[1].toDouble(&ok);
906 if ( !ok )
907 {
908 newCondition.val2 = listVal[1].toInt(&ok);
909 if ( !ok )
910 {
911 newCondition.strVal2 = new TQString( listVal[1] );
912 kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
913 }
914 }
915}
916
917
918bool OpenCalcImport::readRowsAndCells( TQDomElement & content, Sheet * table )
919{
920 kdDebug(30518) << endl << "Reading in rows " << endl;
921
922 int i = 1;
923 int row = 1;
924 int columns = 1;
925 int backupRow = 1;
926 TQDomElement * rowStyle = 0;
927 //Cell* cell = 0;
928 //Cell* cellDest = 0;
929 //Cell* defCell = table->defaultCell();
930 TQDomNode rowNode = KoDom::namedItemNS( content, ooNS::table, "table-row" );
931
932 while ( !rowNode.isNull() )
933 {
934 bool collapsed = false;
935
936 int number = 1;
937 TQDomElement r = rowNode.toElement();
938
939 if ( r.isNull() )
940 return false;
941
942 if ( r.hasAttributeNS( ooNS::table, "style-name" ) )
943 {
944 TQString style = r.attributeNS( ooNS::table, "style-name", TQString() );
945 rowStyle = m_styles[ style ];
946 kdDebug(30518) << "Row style: " << style << endl;
947 }
948
949 collapsed = ( r.attributeNS( ooNS::table, "visibility", TQString() ) == "collapse" );
950
951 backupRow = row;
952
953 rowNode = rowNode.nextSibling();
954
955 if ( !readRowFormat( r, rowStyle, table, row, number, rowNode.isNull() ) ) // updates "row"
956 return false;
957
958 if ( !readCells( r, table, backupRow, columns ) )
959 return false;
960
961 RowFormat * srcLayout = table->nonDefaultRowFormat( backupRow );
962 RowFormat * layout = 0;
963
964 if ( collapsed )
965 srcLayout->setHide( true );
966
967 for ( i = 1; i < number; ++i )
968 {
969 layout = table->nonDefaultRowFormat( backupRow + i );
970
971 layout->copy( *srcLayout );
972
973 /*
974 * TODO: Test: do we need to copy the cells, too?
975 * if so we will probably also need to copy them for repeated col layouts.
976 for ( j = 1; j <= columns; ++j )
977 {
978 Cell* cell = table->cellAt( j, backupRow );
979
980 kdDebug(30518) << "Cell: " << cell << "DefCell: " << defCell << endl;
981 if ( cell && (cell != defCell) )
982 {
983 cellDest = table->nonDefaultCell( j, backupRow + i );
984 cellDest->copyAll( cell );
985 }
986 }
987 */
988 }
989
990 rowStyle = 0;
991 columns = 1;
992 }
993
994 kdDebug(30518) << "Reading in rows done" << endl << endl;
995
996 return true;
997}
998
999bool OpenCalcImport::readColLayouts( TQDomElement & content, Sheet * table )
1000{
1001 kdDebug(30518) << endl << "Reading in columns..." << endl;
1002
1003 TQDomNode colLayout = KoDom::namedItemNS( content, ooNS::table, "table-column" );
1004 int column = 1;
1005
1006 while ( !colLayout.isNull() )
1007 {
1008 if ( colLayout.nodeName() != "table:table-column" )
1009 return true; // all cols read in.
1010
1011 TQDomElement e = colLayout.toElement();
1012
1013 if ( e.isNull() )
1014 return false; // error, that's it...
1015
1016 kdDebug(30518) << "New column: " << column << endl;
1017
1018 int number = 1;
1019 double width = -1.0;
1020 bool collapsed = ( e.attributeNS( ooNS::table, "visibility", TQString() ) == "collapse" );
1021 bool insertPageBreak = false;
1022 Format styleLayout( table, table->doc()->styleManager()->defaultStyle() );
1023
1024 kdDebug(30518) << "Check table:number-columns-repeated" << endl;
1025 if ( e.hasAttributeNS( ooNS::table, "number-columns-repeated" ) )
1026 {
1027 bool ok = true;
1028 number = e.attributeNS( ooNS::table, "number-columns-repeated", TQString() ).toInt( &ok );
1029 if ( !ok )
1030 number = 1;
1031
1032 kdDebug(30518) << "Repeated: " << number << endl;
1033 }
1034
1035 kdDebug(30518) << "Checking table:default-cell-style-name" << endl;
1036 if ( e.hasAttributeNS( ooNS::table, "default-cell-style-name" ) )
1037 {
1038 TQString n( e.attributeNS( ooNS::table, "default-cell-style-name", TQString() ) );
1039 kdDebug(30518) << "Has attribute default-cell-style-name: " << n << endl;
1040 Format * defaultStyle = m_defaultStyles[ n ];
1041 if ( !defaultStyle )
1042 {
1043 TQString name = e.attributeNS( ooNS::table, "default-cell-style-name", TQString() );
1044 TQDomElement * st = m_styles[ name ];
1045
1046 kdDebug(30518) << "Default cell style: " << name << endl;
1047
1048 if ( st && !st->isNull() )
1049 {
1050 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
1051
1052 readInStyle( layout, *st );
1053
1054 m_defaultStyles.insert( name, layout );
1055 kdDebug(30518) << "Insert default cell style: " << name << endl;
1056
1057 defaultStyle = layout;
1058 }
1059 }
1060
1061 if ( defaultStyle )
1062 {
1063 // kdDebug(30518) << "Copying default style, Font: " << defaultStyle->font().toString() << endl;
1064 styleLayout.copy( *defaultStyle );
1065 }
1066 }
1067
1068 TQDomElement * colStyle = 0;
1069 if ( e.hasAttributeNS( ooNS::table, "style-name" ) )
1070 {
1071 TQString style = e.attributeNS( ooNS::table, "style-name", TQString() );
1072 colStyle = m_styles[ style ];
1073
1074 kdDebug(30518) << "Col Style: " << style << endl;
1075 }
1076
1077 TQDomNode node;
1078
1079 if ( colStyle )
1080 node = colStyle->firstChild();
1081
1082 while( !node.isNull() )
1083 {
1084 TQDomElement property = node.toElement();
1085 if ( !property.isNull() && property.localName() == "properties" && property.namespaceURI() == ooNS::style )
1086 {
1087 if ( property.hasAttributeNS( ooNS::style, "column-width" ) )
1088 {
1089 TQString sWidth = property.attributeNS( ooNS::style, "column-width", TQString() );
1090 width = KoUnit::parseValue( property.attributeNS( ooNS::style, "column-width", TQString() ), width );
1091 kdDebug(30518) << "Col Width: " << sWidth << endl;
1092 }
1093
1094 if ( property.hasAttributeNS( ooNS::fo, "break-before" ) )
1095 {
1096 if ( property.attributeNS( ooNS::fo, "break-before", TQString() ) == "page" )
1097 {
1098 insertPageBreak = true;
1099 }
1100 }
1101
1102 loadStyleProperties( &styleLayout, property );
1103 }
1104
1105 node = node.nextSibling();
1106 }
1107
1108 colLayout = colLayout.nextSibling();
1109
1110 if ( colLayout.isNull() && ( number > 30 ) )
1111 number = 30;
1112
1113 for ( int i = 0; i < number; ++i )
1114 {
1115 kdDebug(30518) << "Inserting colLayout: " << column << endl;
1116
1117 ColumnFormat * col = new ColumnFormat( table, column );
1118 col->copy( styleLayout );
1119 if ( width != -1.0 )
1120 col->setWidth( int( width ) );
1121
1122 // if ( insertPageBreak )
1123 // col->setPageBreak( true )
1124
1125 if ( collapsed )
1126 col->setHide( true );
1127
1128 table->insertColumnFormat( col );
1129 ++column;
1130 }
1131 }
1132
1133 return true;
1134}
1135
1136void replaceMacro( TQString & text, TQString const & old, TQString const & newS )
1137{
1138 int n = text.find( old );
1139 if ( n != -1 )
1140 text = text.replace( n, old.length(), newS );
1141}
1142
1143TQString getPart( TQDomNode const & part )
1144{
1145 TQString result;
1146 TQDomElement e = KoDom::namedItemNS( part, ooNS::text, "p" );
1147 while ( !e.isNull() )
1148 {
1149 TQString text = e.text();
1150 kdDebug(30518) << "PART: " << text << endl;
1151
1152 TQDomElement macro = KoDom::namedItemNS( e, ooNS::text, "time" );
1153 if ( !macro.isNull() )
1154 replaceMacro( text, macro.text(), "<time>" );
1155
1156 macro = KoDom::namedItemNS( e, ooNS::text, "date" );
1157 if ( !macro.isNull() )
1158 replaceMacro( text, macro.text(), "<date>" );
1159
1160 macro = KoDom::namedItemNS( e, ooNS::text, "page-number" );
1161 if ( !macro.isNull() )
1162 replaceMacro( text, macro.text(), "<page>" );
1163
1164 macro = KoDom::namedItemNS( e, ooNS::text, "page-count" );
1165 if ( !macro.isNull() )
1166 replaceMacro( text, macro.text(), "<pages>" );
1167
1168 macro = KoDom::namedItemNS( e, ooNS::text, "sheet-name" );
1169 if ( !macro.isNull() )
1170 replaceMacro( text, macro.text(), "<sheet>" );
1171
1172 macro = KoDom::namedItemNS( e, ooNS::text, "title" );
1173 if ( !macro.isNull() )
1174 replaceMacro( text, macro.text(), "<name>" );
1175
1176 macro = KoDom::namedItemNS( e, ooNS::text, "file-name" );
1177 if ( !macro.isNull() )
1178 replaceMacro( text, macro.text(), "<file>" );
1179
1180 if ( !result.isEmpty() )
1181 result += '\n';
1182 result += text;
1183 e = e.nextSibling().toElement();
1184 }
1185
1186 return result;
1187}
1188
1189void OpenCalcImport::loadTableMasterStyle( Sheet * table,
1190 TQString const & stylename )
1191{
1192 kdDebug(30518) << "Loading table master style: " << stylename << endl;
1193
1194 TQDomElement * style = m_styles[ stylename ];
1195
1196 if ( !style )
1197 {
1198 kdDebug(30518) << "Master style not found! " << endl;
1199 return;
1200 }
1201
1202 TQDomNode header = KoDom::namedItemNS( *style, ooNS::style, "header" );
1203 kdDebug(30518) << "Style header " << endl;
1204
1205 TQString hleft, hmiddle, hright;
1206 TQString fleft, fmiddle, fright;
1207
1208 if ( !header.isNull() )
1209 {
1210 kdDebug(30518) << "Header exists" << endl;
1211 TQDomNode part = KoDom::namedItemNS( header, ooNS::style, "region-left" );
1212 if ( !part.isNull() )
1213 {
1214 hleft = getPart( part );
1215 kdDebug(30518) << "Header left: " << hleft << endl;
1216 }
1217 else
1218 kdDebug(30518) << "Style:region:left doesn't exist!" << endl;
1219 part = KoDom::namedItemNS( header, ooNS::style, "region-center" );
1220 if ( !part.isNull() )
1221 {
1222 hmiddle = getPart( part );
1223 kdDebug(30518) << "Header middle: " << hmiddle << endl;
1224 }
1225 part = KoDom::namedItemNS( header, ooNS::style, "region-right" );
1226 if ( !part.isNull() )
1227 {
1228 hright = getPart( part );
1229 kdDebug(30518) << "Header right: " << hright << endl;
1230 }
1231 }
1232
1233 TQDomNode footer = KoDom::namedItemNS( *style, ooNS::style, "footer" );
1234
1235 if ( !footer.isNull() )
1236 {
1237 TQDomNode part = KoDom::namedItemNS( footer, ooNS::style, "region-left" );
1238 if ( !part.isNull() )
1239 {
1240 fleft = getPart( part );
1241 kdDebug(30518) << "Footer left: " << fleft << endl;
1242 }
1243 part = KoDom::namedItemNS( footer, ooNS::style, "region-center" );
1244 if ( !part.isNull() )
1245 {
1246 fmiddle = getPart( part );
1247 kdDebug(30518) << "Footer middle: " << fmiddle << endl;
1248 }
1249 part = KoDom::namedItemNS( footer, ooNS::style, "region-right" );
1250 if ( !part.isNull() )
1251 {
1252 fright = getPart( part );
1253 kdDebug(30518) << "Footer right: " << fright << endl;
1254 }
1255 }
1256
1257 table->print()->setHeadFootLine( hleft, hmiddle, hright,
1258 fleft, fmiddle, fright );
1259 if ( style->hasAttributeNS( ooNS::style, "page-master-name" ) )
1260 {
1261 TQString masterPageLayoutStyleName=style->attributeNS( ooNS::style, "page-master-name", TQString() );
1262 kdDebug(30518)<<"masterPageLayoutStyleName :"<<masterPageLayoutStyleName<<endl;
1263 TQDomElement *masterLayoutStyle = m_styles[masterPageLayoutStyleName];
1264 kdDebug(30518)<<"masterLayoutStyle :"<<masterLayoutStyle<<endl;
1265 if ( !masterLayoutStyle )
1266 return;
1267 KoStyleStack styleStack( ooNS::style, ooNS::fo );
1268 styleStack.push( *masterLayoutStyle );
1269 loadOasisMasterLayoutPage( table, styleStack );
1270 }
1271}
1272
1273void OpenCalcImport::loadOasisMasterLayoutPage( Sheet * table,KoStyleStack &styleStack )
1274{
1275 float left = 0.0;
1276 float right = 0.0;
1277 float top = 0.0;
1278 float bottom = 0.0;
1279 float width = 0.0;
1280 float height = 0.0;
1281 TQString orientation = "Portrait";
1282 TQString format;
1283
1284 // Laurent : Why we stored layout information as Millimeter ?!!!!!
1285 // kspread used point for all other attribute
1286 // I don't understand :(
1287 if ( styleStack.hasAttributeNS( ooNS::fo, "page-width" ) )
1288 {
1289 width = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-width" ) ) );
1290 }
1291 if ( styleStack.hasAttributeNS( ooNS::fo, "page-height" ) )
1292 {
1293 height = KoUnit::toMM( KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "page-height" ) ) );
1294 }
1295 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-top" ) )
1296 {
1297 top = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-top" ) ) );
1298 }
1299 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-bottom" ) )
1300 {
1301 bottom = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-bottom" ) ) );
1302 }
1303 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-left" ) )
1304 {
1305 left = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-left" ) ) );
1306 }
1307 if ( styleStack.hasAttributeNS( ooNS::fo, "margin-right" ) )
1308 {
1309 right = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( ooNS::fo, "margin-right" ) ) );
1310 }
1311 if ( styleStack.hasAttributeNS( ooNS::style, "writing-mode" ) )
1312 {
1313 kdDebug(30518)<<"styleStack.hasAttribute( style:writing-mode ) :"<<styleStack.hasAttributeNS( ooNS::style, "writing-mode" )<<endl;
1314 }
1315 if ( styleStack.hasAttributeNS( ooNS::style, "print-orientation" ) )
1316 {
1317 orientation = ( styleStack.attributeNS( ooNS::style, "print-orientation" )=="landscape" ) ? "Landscape" : "Portrait" ;
1318 }
1319 if ( styleStack.hasAttributeNS( ooNS::style, "num-format" ) )
1320 {
1321 kdDebug(30518)<<" num-format :"<<styleStack.attributeNS( ooNS::style, "num-format" )<<endl;
1322 //todo fixme
1323 }
1324 if ( styleStack.hasAttributeNS( ooNS::fo, "background-color" ) )
1325 {
1326 //todo
1327 kdDebug(30518)<<" fo:background-color :"<<styleStack.attributeNS( ooNS::fo, "background-color" )<<endl;
1328 }
1329 if ( styleStack.hasAttributeNS( ooNS::style, "print" ) )
1330 {
1331 //todo parsing
1332 TQString str = styleStack.attributeNS( ooNS::style, "print" );
1333 kdDebug(30518)<<" style:print :"<<str<<endl;
1334
1335 if (str.contains( "headers" ) )
1336 {
1337 //todo implement it into kspread
1338 }
1339 if ( str.contains( "grid" ) )
1340 {
1341 table->print()->setPrintGrid( true );
1342 }
1343 if ( str.contains( "annotations" ) )
1344 {
1345 //todo it's not implemented
1346 }
1347 if ( str.contains( "objects" ) )
1348 {
1349 //todo it's not implemented
1350 }
1351 if ( str.contains( "charts" ) )
1352 {
1353 //todo it's not implemented
1354 }
1355 if ( str.contains( "drawings" ) )
1356 {
1357 //todo it's not implemented
1358 }
1359 if ( str.contains( "formulas" ) )
1360 {
1361 table->setShowFormula(true);
1362 }
1363 if ( str.contains( "zero-values" ) )
1364 {
1365 //todo it's not implemented
1366 }
1367 }
1368 if ( styleStack.hasAttributeNS( ooNS::style, "table-centering" ) )
1369 {
1370 TQString str = styleStack.attributeNS( ooNS::style, "table-centering" );
1371 //not implemented into kspread
1372 kdDebug(30518)<<" styleStack.attribute( style:table-centering ) :"<<str<<endl;
1373#if 0
1374 if ( str == "horizontal" )
1375 {
1376 }
1377 else if ( str == "vertical" )
1378 {
1379 }
1380 else if ( str == "both" )
1381 {
1382 }
1383 else if ( str == "none" )
1384 {
1385 }
1386 else
1387 kdDebug(30518)<<" table-centering unknown :"<<str<<endl;
1388#endif
1389 }
1390 format = TQString( "%1x%2" ).arg( width ).arg( height );
1391 kdDebug(30518)<<" format : "<<format<<endl;
1392 table->print()->setPaperLayout( left, top, right, bottom, format, orientation );
1393
1394 kdDebug(30518)<<" left margin :"<<left<<" right :"<<right<<" top :"<<top<<" bottom :"<<bottom<<endl;
1395//<style:properties fo:page-width="21.8cm" fo:page-height="28.801cm" fo:margin-top="2cm" fo:margin-bottom="2.799cm" fo:margin-left="1.3cm" fo:margin-right="1.3cm" style:writing-mode="lr-tb"/>
1396// TQString format = paper.attribute( "format" );
1397// TQString orientation = paper.attribute( "orientation" );
1398// m_pPrint->setPaperLayout( left, top, right, bottom, format, orientation );
1399// }
1400}
1401
1402
1403bool OpenCalcImport::parseBody( int numOfTables )
1404{
1405 TQDomElement content = m_content.documentElement();
1406 TQDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
1407
1408 if ( body.isNull() )
1409 return false;
1410
1411 loadOasisAreaName( body.toElement() );
1412 loadOasisCellValidation( body.toElement() );
1413
1414 Sheet * table;
1415 TQDomNode sheet = KoDom::namedItemNS( body, ooNS::table, "table" );
1416
1417 kdDebug()<<" sheet :"<<sheet.isNull()<<endl;
1418 if ( sheet.isNull() )
1419 return false;
1420
1421 while ( !sheet.isNull() )
1422 {
1423 TQDomElement t = sheet.toElement();
1424 if ( t.isNull() )
1425 {
1426 sheet = sheet.nextSibling();
1427 continue;
1428 }
1429 if ( t.nodeName() != "table:table" )
1430 {
1431 sheet = sheet.nextSibling();
1432 continue;
1433 }
1434
1435 table = m_doc->map()->addNewSheet();
1436
1437 table->setSheetName( t.attributeNS( ooNS::table, "name", TQString() ), true, false );
1438 kdDebug()<<" table->name()"<<table->name()<<endl;
1439 sheet = sheet.nextSibling();
1440 }
1441
1442 sheet = body.firstChild();
1443
1444 int step = (int) ( 80 / numOfTables );
1445 int progress = 15;
1446
1447 Format::setGlobalColWidth( MM_TO_POINT( 22.7 ) );
1448 Format::setGlobalRowHeight( MM_TO_POINT( 4.3 ) );
1449 kdDebug(30518) << "Global Height: " << MM_TO_POINT( 4.3 ) << ", Global width: " << MM_TO_POINT( 22.7) << endl;
1450
1451 while ( !sheet.isNull() )
1452 {
1453 TQDomElement t = sheet.toElement();
1454 if ( t.isNull() )
1455 {
1456 KMessageBox::sorry( 0, i18n( "The file seems to be corrupt. Skipping a table." ) );
1457 sheet = sheet.nextSibling();
1458 continue;
1459 }
1460 if ( t.nodeName() != "table:table" )
1461 {
1462 sheet = sheet.nextSibling();
1463 continue;
1464 }
1465
1466 table = m_doc->map()->findSheet( t.attributeNS( ooNS::table, "name", TQString() ) );
1467 if ( !table )
1468 {
1469 KMessageBox::sorry( 0, i18n( "Skipping a table." ) );
1470 sheet = sheet.nextSibling();
1471 continue;
1472 }
1473
1474 Format * defaultStyle = m_defaultStyles[ "Default" ];
1475 if ( defaultStyle )
1476 {
1477 Cell* defaultCell = table->defaultCell();
1478 kdDebug(30518) << "Copy default style to default cell" << endl;
1479 defaultCell->format()->copy( *defaultStyle );
1480 }
1481 table->setDefaultHeight( MM_TO_POINT( 4.3 ) );
1482 table->setDefaultWidth( MM_TO_POINT( 22.7 ) );
1483
1484 kdDebug(30518) << "Added table: " << t.attributeNS( ooNS::table, "name", TQString() ) << endl;
1485
1486 if ( t.hasAttributeNS( ooNS::table, "style-name" ) )
1487 {
1488 TQString style = t.attributeNS( ooNS::table, "style-name", TQString() );
1489 TQDomElement * tableStyle = m_styles[ style ];
1490
1491 TQDomNode node;
1492
1493 if ( tableStyle )
1494 node = tableStyle->firstChild();
1495
1496 while( !node.isNull() )
1497 {
1498 TQDomElement property = node.toElement();
1499 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
1500 {
1501 if ( property.hasAttributeNS( ooNS::table, "display" ) )
1502 {
1503 bool visible = (property.attributeNS( ooNS::table, "display", TQString() ) == "true" ? true : false );
1504 table->hideSheet( !visible );
1505 kdDebug(30518) << "Table: " << table->tableName() << ", hidden: " << !visible << endl;
1506 }
1507 }
1508
1509 node = node.nextSibling();
1510 }
1511
1512 if ( tableStyle && tableStyle->hasAttributeNS( ooNS::style, "master-page-name" ) )
1513 {
1514 TQString stylename = "pm" + tableStyle->attributeNS( ooNS::style, "master-page-name", TQString() );
1515
1516 loadTableMasterStyle( table, stylename );
1517
1518 }
1519 }
1520 if ( t.hasAttributeNS( ooNS::table, "print-ranges" ) )
1521 {
1522 // e.g.: Sheet4.A1:Sheet4.E28
1523 TQString range = t.attributeNS( ooNS::table, "print-ranges", TQString() );
1524 OpenCalcPoint point( range );
1525
1526 kdDebug(30518) << "Print range: " << point.translation << endl;
1527 KSpread::Range p( point.translation );
1528
1529 kdDebug(30518) << "Print table: " << p.sheetName() << endl;
1530
1531 if ( table->sheetName() == p.sheetName() )
1532 table->print()->setPrintRange( p.range() );
1533 }
1534
1535 if ( !readColLayouts( t, table ) )
1536 return false;
1537
1538 if ( !readRowsAndCells( t, table ) )
1539 return false;
1540
1541 if ( t.hasAttributeNS( ooNS::table, "protected" ) )
1542 {
1543 TQCString passwd( "" );
1544 if ( t.hasAttributeNS( ooNS::table, "protection-key" ) )
1545 {
1546 TQString p = t.attributeNS( ooNS::table, "protection-key", TQString() );
1547 TQCString str( p.latin1() );
1548 kdDebug(30518) << "Decoding password: " << str << endl;
1549 passwd = KCodecs::base64Decode( str );
1550 }
1551 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
1552 table->setProtected( passwd );
1553 }
1554
1555 progress += step;
1556 emit sigProgress( progress );
1557 sheet = sheet.nextSibling();
1558 }
1559
1560 TQDomElement b = body.toElement();
1561 if ( b.hasAttributeNS( ooNS::table, "structure-protected" ) )
1562 {
1563 TQCString passwd( "" );
1564 if ( b.hasAttributeNS( ooNS::table, "protection-key" ) )
1565 {
1566 TQString p = b.attributeNS( ooNS::table, "protection-key", TQString() );
1567 TQCString str( p.latin1() );
1568 kdDebug(30518) << "Decoding password: " << str << endl;
1569 passwd = KCodecs::base64Decode( str );
1570 }
1571 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
1572
1573 m_doc->map()->setProtected( passwd );
1574 }
1575
1576 emit sigProgress( 98 );
1577
1578 return true;
1579}
1580
1581void OpenCalcImport::insertStyles( TQDomElement const & element )
1582{
1583 if ( element.isNull() )
1584 return;
1585
1586 TQDomElement e;
1587 forEachElement( e, element )
1588 {
1589 if ( e.isNull() || !e.hasAttributeNS( ooNS::style, "name" ) )
1590 {
1591 continue;
1592 }
1593
1594 TQString name = e.attributeNS( ooNS::style, "name", TQString() );
1595 kdDebug(30518) << "Style: '" << name << "' loaded " << endl;
1596 m_styles.insert( name, new TQDomElement( e ) );
1597 }
1598}
1599
1600
1601void OpenCalcImport::loadOasisAreaName( const TQDomElement&body )
1602{
1603 TQDomNode namedAreas = KoDom::namedItemNS( body, ooNS::table, "named-expressions" );
1604 if ( !namedAreas.isNull() )
1605 {
1606 TQDomElement e;
1607 forEachElement( e, namedAreas )
1608 {
1609 if ( e.isNull() || !e.hasAttributeNS( ooNS::table, "name" ) || !e.hasAttributeNS( ooNS::table, "cell-range-address" ) )
1610 {
1611 kdDebug(30518) << "Reading in named area failed" << endl;
1612 continue;
1613 }
1614
1615 // TODO: what is: table:base-cell-address
1616 TQString name = e.attributeNS( ooNS::table, "name", TQString() );
1617 TQString areaPoint = e.attributeNS( ooNS::table, "cell-range-address", TQString() );
1618
1619 m_namedAreas.append( name );
1620 kdDebug(30518) << "Reading in named area, name: " << name << ", area: " << areaPoint << endl;
1621
1622 OpenCalcPoint point( areaPoint );
1623 kdDebug(30518) << "Area: " << point.translation << endl;
1624
1625 TQString range( point.translation );
1626
1627 if ( point.translation.find( ':' ) == -1 )
1628 {
1629 Point p( point.translation );
1630
1631 int n = range.find( '!' );
1632 if ( n > 0 )
1633 range = range + ":" + range.right( range.length() - n - 1);
1634
1635 kdDebug(30518) << "=> Area: " << range << endl;
1636 }
1637
1638 KSpread::Range p( range );
1639
1640 m_doc->addAreaName( p.range(), name, p.sheetName() );
1641 kdDebug(30518) << "Area range: " << p.sheetName() << endl;
1642 }
1643 }
1644}
1645
1646void OpenCalcImport::loadOasisCellValidation( const TQDomElement&body )
1647{
1648 TQDomNode validation = KoDom::namedItemNS( body, ooNS::table, "content-validations" );
1649 if ( !validation.isNull() )
1650 {
1651 TQDomElement element;
1652 forEachElement( element, validation )
1653 {
1654 if ( element.localName() == "content-validation" ) {
1655 m_validationList.insert( element.attributeNS( ooNS::table, "name", TQString() ), element);
1656 kdDebug(30518)<<" validation found :"<<element.attributeNS( ooNS::table, "name", TQString() )<<endl;
1657 }
1658 else {
1659 kdDebug(30518)<<" Tag not recognize :"<<element.tagName()<<endl;
1660 }
1661 }
1662 }
1663}
1664
1665
1666TQString * OpenCalcImport::loadFormat( TQDomElement * element,
1667 FormatType & formatType,
1668 TQString name )
1669{
1670 if ( !element )
1671 return 0;
1672
1673 int i;
1674 bool ok;
1675
1676 TQString * format = 0;
1677 TQDomElement e = element->firstChild( ).toElement();
1678 int precision = 0;
1679 int leadingZ = 1;
1680 bool thousandsSep = false;
1681 bool negRed = false;
1682
1683 if ( element->localName() == "time-style" )
1684 formatType = Custom_format;
1685 else if ( element->localName() == "date-style" )
1686 formatType = Custom_format;
1687 else if ( element->localName() == "percentage-style" )
1688 formatType = Custom_format;
1689 else if ( element->localName() == "number-style" )
1690 formatType = Custom_format;
1691 else if ( element->localName() == "currency-style" )
1692 formatType = Custom_format;
1693 else if ( element->localName() == "boolean-style" )
1694 formatType = Custom_format;
1695
1696 if ( !e.isNull() )
1697 format = new TQString();
1698
1699 // TODO (element):
1700 // number:automatic-order="true"
1701 // number:truncate-on-overflow="false"
1702 // style:volatile="true"
1703
1704 while ( !e.isNull() )
1705 {
1706 if ( e.localName() == "properties" && e.namespaceURI() == ooNS::style )
1707 {
1708 if ( e.hasAttributeNS( ooNS::fo, "color" ) )
1709 negRed = true; // we only support red...
1710 }
1711 else if ( e.localName() == "text" && e.namespaceURI()==ooNS::number)
1712 {
1713 if ( negRed && ( e.text() == "-" ) )
1714 ;
1715 else
1716 format->append( e.text() );
1717 }
1718 else if ( e.localName() == "currency-symbol" && e.namespaceURI()==ooNS::number)
1719 {
1720 TQString sym( e.text() );
1721 kdDebug(30518) << "Currency: " << sym << endl;
1722 format->append( sym );
1723 // number:language="de" number:country="DE">€</number:currency-symbol>
1724 }
1725 else if ( e.localName() == "day-of-week" && e.namespaceURI()==ooNS::number)
1726 {
1727 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1728 {
1729 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1730 format->append( "dddd" );
1731 else
1732 format->append( "ddd" );
1733 }
1734 else
1735 format->append( "ddd" );
1736 }
1737 else if ( e.localName() == "day" && e.namespaceURI()==ooNS::number)
1738 {
1739 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1740 {
1741 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1742 format->append( "dd" );
1743 else
1744 format->append( "d" );
1745 }
1746 else
1747 format->append( "d" );
1748 }
1749 else if ( e.localName() == "month" && e.namespaceURI()==ooNS::number)
1750 {
1751 if ( e.hasAttributeNS( ooNS::number, "textual" ) )
1752 {
1753 if ( e.attributeNS( ooNS::number, "textual", TQString() ) == "true" )
1754 format->append( "mm" );
1755 }
1756
1757 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1758 {
1759 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1760 format->append( "mm" );
1761 else
1762 format->append( "m" );
1763 }
1764 else
1765 format->append( "m" );
1766 }
1767 else if ( e.localName() == "year" && e.namespaceURI()==ooNS::number)
1768 {
1769 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1770 {
1771 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1772 format->append( "yyyy" );
1773 else
1774 format->append( "yy" );
1775 }
1776 else
1777 format->append( "yy" );
1778 }
1779 else if ( e.localName() == "hours" && e.namespaceURI()==ooNS::number)
1780 {
1781 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1782 {
1783 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1784 format->append( "hh" );
1785 else
1786 format->append( "h" );
1787 }
1788 else
1789 format->append( "h" );
1790 }
1791 else if ( e.localName() == "minutes" && e.namespaceURI()==ooNS::number)
1792 {
1793 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1794 {
1795 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1796 format->append( "mm" );
1797 else
1798 format->append( "m" );
1799 }
1800 else
1801 format->append( "m" );
1802 }
1803 else if ( e.localName() == "seconds" && e.namespaceURI()==ooNS::number)
1804 {
1805 if ( e.hasAttributeNS( ooNS::number, "style" ) )
1806 {
1807 if ( e.attributeNS( ooNS::number, "style", TQString() ) == "long" )
1808 format->append( "ss" );
1809 else
1810 format->append( "s" );
1811 }
1812 else
1813 format->append( "s" );
1814 }
1815 else if ( e.localName() == "am-pm" && e.namespaceURI()==ooNS::number)
1816 {
1817 format->append( "AM/PM" );
1818 }
1819 else if ( e.localName() == "number" && e.namespaceURI()==ooNS::number)
1820 {
1821 // TODO: number:grouping="true"
1822
1823 if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
1824 {
1825 int d = e.attributeNS( ooNS::number, "decimal-places", TQString() ).toInt( &ok );
1826 if ( ok )
1827 precision = d;
1828 }
1829
1830 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
1831 {
1832 int d = e.attributeNS( ooNS::number, "min-integer-digits", TQString() ).toInt( &ok );
1833 if ( ok )
1834 leadingZ = d;
1835 }
1836
1837 if ( thousandsSep && leadingZ <= 3 )
1838 {
1839 format->append( "#," );
1840 for ( i = leadingZ; i <= 3; ++i )
1841 format->append( '#' );
1842 }
1843
1844 for ( i = 1; i <= leadingZ; ++i )
1845 {
1846 format->append( '0' );
1847 if ( ( i % 3 == 0 ) && thousandsSep )
1848 format->append( ',' );
1849 }
1850
1851 format->append( '.' );
1852 for ( i = 0; i < precision; ++i )
1853 format->append( '0' );
1854 }
1855 else if ( e.localName() == "scientific-number" && e.namespaceURI()==ooNS::number)
1856 {
1857 int exp = 2;
1858
1859 if ( e.hasAttributeNS( ooNS::number, "decimal-places" ) )
1860 {
1861 int d = e.attributeNS( ooNS::number, "decimal-places", TQString() ).toInt( &ok );
1862 if ( ok )
1863 precision = d;
1864 }
1865
1866 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
1867 {
1868 int d = e.attributeNS( ooNS::number, "min-integer-digits", TQString() ).toInt( &ok );
1869 if ( ok )
1870 leadingZ = d;
1871 }
1872
1873 if ( e.hasAttributeNS( ooNS::number, "min-exponent-digits" ) )
1874 {
1875 int d = e.attributeNS( ooNS::number, "min-exponent-digits", TQString() ).toInt( &ok );
1876 if ( ok )
1877 exp = d;
1878 if ( exp <= 0 )
1879 exp = 1;
1880 }
1881
1882 if ( thousandsSep && leadingZ <= 3 )
1883 {
1884 format->append( "#," );
1885 for ( i = leadingZ; i <= 3; ++i )
1886 format->append( '#' );
1887 }
1888
1889 for ( i = 1; i <= leadingZ; ++i )
1890 {
1891 format->append( '0' );
1892 if ( ( i % 3 == 0 ) && thousandsSep )
1893 format->append( ',' );
1894 }
1895
1896 format->append( '.' );
1897 for ( i = 0; i < precision; ++i )
1898 format->append( '0' );
1899
1900 format->append( "E+" );
1901 for ( i = 0; i < exp; ++i )
1902 format->append( '0' );
1903
1904 formatType = Custom_format;
1905 }
1906 else if ( e.localName() == "fraction" && e.namespaceURI()==ooNS::number)
1907 {
1908 int integer = 0;
1909 int numerator = 1;
1910 int denominator = 1;
1911
1912 if ( e.hasAttributeNS( ooNS::number, "min-integer-digits" ) )
1913 {
1914 int d = e.attributeNS( ooNS::number, "min-integer-digits", TQString() ).toInt( &ok );
1915 if ( ok )
1916 integer = d;
1917 }
1918 if ( e.hasAttributeNS( ooNS::number, "min-numerator-digits" ) )
1919 {
1920 int d = e.attributeNS( ooNS::number, "min-numerator-digits", TQString() ).toInt( &ok );
1921 if ( ok )
1922 numerator = d;
1923 }
1924 if ( e.hasAttributeNS( ooNS::number, "min-denominator-digits" ) )
1925 {
1926 int d = e.attributeNS( ooNS::number, "min-denominator-digits", TQString() ).toInt( &ok );
1927 if ( ok )
1928 denominator = d;
1929 }
1930
1931 for ( i = 0; i <= integer; ++i )
1932 format->append( '#' );
1933
1934 format->append( ' ' );
1935
1936 for ( i = 0; i <= numerator; ++i )
1937 format->append( '?' );
1938
1939 format->append( '/' );
1940
1941 for ( i = 0; i <= denominator; ++i )
1942 format->append( '?' );
1943 }
1944 // Not needed:
1945 // <style:map style:condition="value()&gt;=0" style:apply-style-name="N106P0"/>
1946 // we handle painting negative numbers in red differently
1947
1948 e = e.nextSibling().toElement();
1949 }
1950
1951 if ( negRed )
1952 {
1953 TQString f( *format );
1954 format->append( ";[Red]" );
1955 format->append( f );
1956 }
1957
1958 kdDebug(30518) << "*** New FormatString: " << *format << endl << endl;
1959
1960 m_formats.insert( name, format );
1961
1962 return format;
1963}
1964
1965void OpenCalcImport::loadFontStyle( Format * layout, TQDomElement const * font ) const
1966{
1967 if ( !font || !layout )
1968 return;
1969
1970 kdDebug(30518) << "Copy font style from the layout " << font->tagName() << ", " << font->nodeName() << endl;
1971
1972 if ( font->hasAttributeNS( ooNS::fo, "font-family" ) )
1973 layout->setTextFontFamily( font->attributeNS( ooNS::fo, "font-family", TQString() ) );
1974 if ( font->hasAttributeNS( ooNS::fo, "color" ) )
1975 layout->setTextColor( TQColor( font->attributeNS( ooNS::fo, "color", TQString() ) ) );
1976 if ( font->hasAttributeNS( ooNS::fo, "font-size" ) )
1977 layout->setTextFontSize( int( KoUnit::parseValue( font->attributeNS( ooNS::fo, "font-size", TQString() ), 10 ) ) );
1978 else
1979 layout->setTextFontSize( 10 );
1980 if ( font->hasAttributeNS( ooNS::fo, "font-style" ) )
1981 {
1982 kdDebug(30518) << "italic" << endl;
1983 layout->setTextFontItalic( true ); // only thing we support
1984 }
1985 if ( font->hasAttributeNS( ooNS::fo, "font-weight" ) )
1986 layout->setTextFontBold( true ); // only thing we support
1987 if ( font->hasAttributeNS( ooNS::fo, "text-underline" ) || font->hasAttributeNS( ooNS::style, "text-underline" ) )
1988 layout->setTextFontUnderline( true ); // only thing we support
1989 if ( font->hasAttributeNS( ooNS::style, "text-crossing-out" ) )
1990 layout->setTextFontStrike( true ); // only thing we support
1991 if ( font->hasAttributeNS( ooNS::style, "font-pitch" ) )
1992 {
1993 // TODO: possible values: fixed, variable
1994 }
1995 // TODO:
1996 // text-underline-color
1997}
1998
1999void OpenCalcImport::loadBorder( Format * layout, TQString const & borderDef, bPos pos ) const
2000{
2001 if ( borderDef == "none" )
2002 return;
2003
2004 int p = borderDef.find( ' ' );
2005 if ( p < 0 )
2006 return;
2007
2008 TQPen pen;
2009 TQString w = borderDef.left( p );
2010 pen.setWidth( (int) KoUnit::parseValue( w ) );
2011
2012
2013 ++p;
2014 int p2 = borderDef.find( ' ', p );
2015 TQString s = borderDef.mid( p, p2 - p );
2016
2017 kdDebug(30518) << "Borderstyle: " << s << endl;
2018
2019 if ( s == "solid" || s == "double" )
2020 pen.setStyle( TQt::SolidLine );
2021 else
2022 {
2023#if 0
2024 // TODO: not supported by oocalc
2025 pen.setStyle( TQt::DashLine );
2026 pen.setStyle( TQt::DotLine );
2027 pen.setStyle( TQt::DashDotLine );
2028 pen.setStyle( TQt::DashDotDotLine );
2029#endif
2030 pen.setStyle( TQt::SolidLine ); //default.
2031 }
2032
2033 ++p2;
2034 p = borderDef.find( ' ', p2 );
2035 if ( p == -1 )
2036 p = borderDef.length();
2037
2038 pen.setColor( TQColor( borderDef.right( p - p2 ) ) );
2039
2040 if ( pos == Left )
2041 layout->setLeftBorderPen( pen );
2042 else if ( pos == Top )
2043 layout->setTopBorderPen( pen );
2044 else if ( pos == Right )
2045 layout->setRightBorderPen( pen );
2046 else if ( pos == Bottom )
2047 layout->setBottomBorderPen( pen );
2048 else if ( pos == Border )
2049 {
2050 layout->setLeftBorderPen( pen );
2051 layout->setTopBorderPen( pen );
2052 layout->setRightBorderPen( pen );
2053 layout->setBottomBorderPen( pen );
2054 }
2055 // TODO Diagonals not supported by oocalc
2056}
2057
2058void OpenCalcImport::loadStyleProperties( Format * layout, TQDomElement const & property ) const
2059{
2060 kdDebug(30518) << "*** Loading style properties *****" << endl;
2061
2062 if ( property.hasAttributeNS( ooNS::style, "decimal-places" ) )
2063 {
2064 bool ok = false;
2065 int p = property.attributeNS( ooNS::style, "decimal-places", TQString() ).toInt( &ok );
2066 if (ok )
2067 layout->setPrecision( p );
2068 }
2069
2070 if ( property.hasAttributeNS( ooNS::style, "font-name" ) )
2071 {
2072 TQDomElement * font = m_styles[ property.attributeNS( ooNS::style, "font-name", TQString() ) ];
2073 loadFontStyle( layout, font ); // generell font style
2074 }
2075
2076 loadFontStyle( layout, &property ); // specific font style
2077
2078 // TODO:
2079 // diagonal: fall + goup
2080 // fo:direction="ltr"
2081 // style:text-align-source ("fix")
2082 // style:shadow
2083 // style:text-outline
2084 // indents from right, top, bottom
2085 // style:condition="cell-content()=15"
2086 // => style:apply-style-name="Result" style:base-cell-address="Sheet6.A5"/>
2087
2088 if ( property.hasAttributeNS( ooNS::style, "rotation-angle" ) )
2089 {
2090 bool ok = false;
2091 int a = property.attributeNS( ooNS::style, "rotation-angle", TQString() ).toInt( &ok );
2092 if ( ok )
2093 layout->setAngle( -a + 1 );
2094 }
2095
2096 if ( property.hasAttributeNS( ooNS::fo, "direction" ) )
2097 {
2098 layout->setVerticalText( true );
2099 }
2100 if ( property.hasAttributeNS( ooNS::fo, "text-align" ) )
2101 {
2102 TQString s = property.attributeNS( ooNS::fo, "text-align", TQString() );
2103 if ( s == "center" )
2104 layout->setAlign( Format::Center );
2105 else if ( s == "end" )
2106 layout->setAlign( Format::Right );
2107 else if ( s == "start" )
2108 layout->setAlign( Format::Left );
2109 else if ( s == "justify" ) // TODO in KSpread!
2110 layout->setAlign( Format::Center );
2111 }
2112 if ( property.hasAttributeNS( ooNS::fo, "margin-left" ) )
2113 {
2114 kdDebug(30518)<<"margin-left :"<<KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", TQString() ),0.0 )<<endl;
2115 layout->setIndent( KoUnit::parseValue( property.attributeNS( ooNS::fo, "margin-left", TQString() ),0.0 ) );
2116 }
2117 if ( property.hasAttributeNS( ooNS::fo, "background-color" ) )
2118 layout->setBgColor( TQColor( property.attributeNS( ooNS::fo, "background-color", TQString() ) ) );
2119
2120 if ( property.hasAttributeNS( ooNS::style, "print-content" ) )
2121 {
2122 if ( property.attributeNS( ooNS::style, "print-content", TQString() ) == "false" )
2123 layout->setDontPrintText( false );
2124 }
2125 if ( property.hasAttributeNS( ooNS::style, "cell-protect" ) )
2126 {
2127 TQString prot( property.attributeNS( ooNS::style, "cell-protect", TQString() ) );
2128 if ( prot == "none" )
2129 {
2130 layout->setNotProtected( true );
2131 layout->setHideFormula( false );
2132 layout->setHideAll( false );
2133 }
2134 else if ( prot == "formula-hidden" )
2135 {
2136 layout->setNotProtected( true );
2137 layout->setHideFormula( true );
2138 layout->setHideAll( false );
2139 }
2140 else if ( prot == "protected formula-hidden" )
2141 {
2142 layout->setNotProtected( false );
2143 layout->setHideFormula( true );
2144 layout->setHideAll( false );
2145 }
2146 else if ( prot == "hidden-and-protected" )
2147 {
2148 layout->setNotProtected( false );
2149 layout->setHideFormula( false );
2150 layout->setHideAll( true );
2151 }
2152 else if ( prot == "protected" )
2153 {
2154 layout->setNotProtected( false );
2155 layout->setHideFormula( false );
2156 layout->setHideAll( false );
2157 }
2158 kdDebug(30518) << "Cell " << prot << endl;
2159 }
2160
2161 if ( property.hasAttributeNS( ooNS::fo, "padding-left" ) )
2162 layout->setIndent( KoUnit::parseValue(property.attributeNS( ooNS::fo, "padding-left", TQString() ) ) );
2163
2164 if ( property.hasAttributeNS( ooNS::fo, "vertical-align" ) )
2165 {
2166 TQString s = property.attributeNS( ooNS::fo, "vertical-align", TQString() );
2167 if ( s == "middle" )
2168 layout->setAlignY( Format::Middle );
2169 else if ( s == "bottom" )
2170 layout->setAlignY( Format::Bottom );
2171 else
2172 layout->setAlignY( Format::Top );
2173 }
2174 else
2175 layout->setAlignY( Format::Bottom );
2176
2177 if ( property.hasAttributeNS( ooNS::fo, "wrap-option" ) )
2178 {
2179 layout->setMultiRow( true );
2180
2181 /* we do not support anything else yet
2182 TQString s = property.attributeNS( ooNS::fo, "wrap-option", TQString() );
2183 if ( s == "wrap" )
2184 layout->setMultiRow( true );
2185 */
2186 }
2187
2188 if ( property.hasAttributeNS( ooNS::fo, "border-bottom" ) )
2189 {
2190 loadBorder( layout, property.attributeNS( ooNS::fo, "border-bottom", TQString() ), Bottom );
2191 // TODO: style:border-line-width-bottom if double!
2192 }
2193
2194 if ( property.hasAttributeNS( ooNS::fo, "border-right" ) )
2195 {
2196 loadBorder( layout, property.attributeNS( ooNS::fo, "border-right", TQString() ), Right );
2197 // TODO: style:border-line-width-right
2198 }
2199
2200 if ( property.hasAttributeNS( ooNS::fo, "border-top" ) )
2201 {
2202 loadBorder( layout, property.attributeNS( ooNS::fo, "border-top", TQString() ), Top );
2203 // TODO: style:border-line-width-top
2204 }
2205
2206 if ( property.hasAttributeNS( ooNS::fo, "border-left" ) )
2207 {
2208 loadBorder( layout, property.attributeNS( ooNS::fo, "border-left", TQString() ), Left );
2209 // TODO: style:border-line-width-left
2210 }
2211
2212 if ( property.hasAttributeNS( ooNS::fo, "border" ) )
2213 {
2214 loadBorder( layout, property.attributeNS( ooNS::fo, "border", TQString() ), Border );
2215 // TODO: style:border-line-width-left
2216 }
2217}
2218
2219void OpenCalcImport::readInStyle( Format * layout, TQDomElement const & style )
2220{
2221 kdDebug(30518) << "** Reading Style: " << style.tagName() << "; " << style.attributeNS( ooNS::style, "name", TQString()) << endl;
2222 if ( style.localName() == "style" && style.namespaceURI()==ooNS::style)
2223 {
2224 if ( style.hasAttributeNS( ooNS::style, "parent-style-name" ) )
2225 {
2226 Format * cp
2227 = m_defaultStyles.find( style.attributeNS( ooNS::style, "parent-style-name", TQString() ) );
2228 kdDebug(30518) << "Copying layout from " << style.attributeNS( ooNS::style, "parent-style-name", TQString() ) << endl;
2229
2230 if ( cp != 0 )
2231 layout->copy( *cp );
2232 }
2233 else if ( style.hasAttributeNS( ooNS::style, "family") )
2234 {
2235 TQString name = style.attribute( "style-family" ) + "default";
2236 Format * cp = m_defaultStyles.find( name );
2237
2238 kdDebug(30518) << "Copying layout from " << name << ", " << !cp << endl;
2239
2240 if ( cp != 0 )
2241 layout->copy( *cp );
2242 }
2243
2244 if ( style.hasAttributeNS( ooNS::style, "data-style-name" ) )
2245 {
2246 TQString * format = m_formats[ style.attributeNS( ooNS::style, "data-style-name", TQString() ) ];
2247 FormatType formatType;
2248
2249 if ( !format )
2250 {
2251 // load and convert it
2252 TQString name( style.attributeNS( ooNS::style, "data-style-name", TQString() ) );
2253 format = loadFormat( m_styles[ name ], formatType, name );
2254 }
2255
2256 if ( format )
2257 {
2258 layout->setFormatString( *format );
2259 layout->setFormatType( formatType );
2260 }
2261
2262 // <number:currency-symbol number:language="de" number:country="DE">€</number:currency-symbol>
2263 }
2264 }
2265
2266 TQDomElement property;
2267 forEachElement( property, style )
2268 {
2269 if ( property.localName() == "properties" && property.namespaceURI() == ooNS::style )
2270 loadStyleProperties( layout, property );
2271
2272 kdDebug(30518) << layout->textFontFamily( 0, 0 ) << endl;
2273 }
2274}
2275
2276bool OpenCalcImport::createStyleMap( TQDomDocument const & styles )
2277{
2278 TQDomElement content = styles.documentElement();
2279 TQDomNode docStyles = KoDom::namedItemNS( content, ooNS::office, "document-styles" );
2280
2281 if ( content.hasAttributeNS( ooNS::office, "version" ) )
2282 {
2283 bool ok = true;
2284 double d = content.attributeNS( ooNS::office, "version", TQString() ).toDouble( &ok );
2285
2286 if ( ok )
2287 {
2288 kdDebug(30518) << "OpenCalc version: " << d << endl;
2289 if ( d > 1.0 )
2290 {
2291 TQString 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?") );
2292 message.arg( content.attributeNS( ooNS::office, "version", TQString() ) );
2293 if ( KMessageBox::warningYesNo( 0, message, i18n( "Unsupported document version" ) ) == KMessageBox::No )
2294 return false;
2295 }
2296 }
2297 }
2298
2299 TQDomNode fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
2300
2301 if ( !fontStyles.isNull() )
2302 {
2303 kdDebug(30518) << "Starting reading in font-decl..." << endl;
2304
2305 insertStyles( fontStyles.toElement() );
2306 }
2307 else
2308 kdDebug(30518) << "No items found" << endl;
2309
2310 kdDebug(30518) << "Starting reading in auto:styles" << endl;
2311
2312 TQDomNode autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
2313 if ( !autoStyles.isNull() )
2314 insertStyles( autoStyles.toElement() );
2315 else
2316 kdDebug(30518) << "No items found" << endl;
2317
2318
2319 kdDebug(30518) << "Reading in master styles" << endl;
2320
2321 TQDomNode masterStyles = KoDom::namedItemNS( content, ooNS::office, "master-styles" );
2322
2323 if ( masterStyles.isNull() )
2324 {
2325 kdDebug(30518) << "Nothing found " << endl;
2326 }
2327
2328 TQDomElement master = KoDom::namedItemNS( masterStyles, ooNS::style, "master-page");
2329 if ( !master.isNull() )
2330 {
2331 TQString name( "pm" );
2332 name += master.attributeNS( ooNS::style, "name", TQString() );
2333 kdDebug(30518) << "Master style: '" << name << "' loaded " << endl;
2334 m_styles.insert( name, new TQDomElement( master ) );
2335
2336 master = master.nextSibling().toElement();
2337 }
2338
2339
2340 kdDebug(30518) << "Starting reading in office:styles" << endl;
2341
2342 TQDomNode fixedStyles = KoDom::namedItemNS( content, ooNS::office, "styles" );
2343
2344 kdDebug(30518) << "Reading in default styles" << endl;
2345
2346 TQDomNode def = KoDom::namedItemNS( fixedStyles, ooNS::style, "default-style" );
2347 kdDebug()<<" def !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<<def.isNull()<<endl;
2348 while ( !def.isNull() )
2349 {
2350 TQDomElement e = def.toElement();
2351 kdDebug(30518) << "Style found " << e.nodeName() << ", tag: " << e.tagName() << endl;
2352
2353 if ( e.nodeName() != "style:default-style" )
2354 {
2355 def = def.nextSibling();
2356 continue;
2357 }
2358
2359 if ( !e.isNull() )
2360 {
2361 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
2362
2363 readInStyle( layout, e );
2364 kdDebug(30518) << "Default style " << e.attributeNS( ooNS::style, "family", TQString() ) << "default" << " loaded " << endl;
2365
2366 m_defaultStyles.insert( e.attributeNS( ooNS::style, "family", TQString() ) + "default", layout );
2367 // TQFont font = layout->font();
2368 // kdDebug(30518) << "Font: " << font.family() << ", " << font.toString() << endl;
2369 }
2370
2371 def = def.nextSibling();
2372 }
2373
2374 TQDomElement defs = KoDom::namedItemNS( fixedStyles, ooNS::style, "style" );
2375 while ( !defs.isNull() )
2376 {
2377 if ( defs.nodeName() != "style:style" )
2378 break; // done
2379
2380 if ( !defs.hasAttributeNS( ooNS::style, "name" ) )
2381 {
2382 // ups...
2383 defs = defs.nextSibling().toElement();
2384 continue;
2385 }
2386
2387 Format * layout = new Format( 0, m_doc->styleManager()->defaultStyle() );
2388 readInStyle( layout, defs );
2389 kdDebug(30518) << "Default style " << defs.attributeNS( ooNS::style, "name", TQString() ) << " loaded " << endl;
2390
2391 m_defaultStyles.insert( defs.attributeNS( ooNS::style, "name", TQString() ), layout );
2392 // kdDebug(30518) << "Font: " << layout->font().family() << ", " << layout->font().toString() << endl;
2393
2394 defs = defs.nextSibling().toElement();
2395 }
2396
2397 if ( !fixedStyles.isNull() )
2398 insertStyles( fixedStyles.toElement() );
2399
2400 kdDebug(30518) << "Starting reading in automatic styles" << endl;
2401
2402 content = m_content.documentElement();
2403 autoStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
2404
2405 if ( !autoStyles.isNull() )
2406 insertStyles( autoStyles.toElement() );
2407
2408 fontStyles = KoDom::namedItemNS( content, ooNS::office, "font-decls" );
2409
2410 if ( !fontStyles.isNull() )
2411 {
2412 kdDebug(30518) << "Starting reading in special font decl" << endl;
2413
2414 insertStyles( fontStyles.toElement() );
2415 }
2416
2417 kdDebug(30518) << "Styles read in." << endl;
2418
2419 return true;
2420}
2421
2422void OpenCalcImport::loadOasisValidation( Validity* val, const TQString& validationName )
2423{
2424 kdDebug(30518)<<"validationName:"<<validationName<<endl;
2425 TQDomElement element = m_validationList[validationName];
2426 if ( element.hasAttributeNS( ooNS::table, "condition" ) )
2427 {
2428 TQString valExpression = element.attributeNS( ooNS::table, "condition", TQString() );
2429 kdDebug(30518)<<" element.attribute( table:condition ) "<<valExpression<<endl;
2430 //Condition ::= ExtendedTrueCondition | TrueFunction 'and' TrueCondition
2431 //TrueFunction ::= cell-content-is-whole-number() | cell-content-is-decimal-number() | cell-content-is-date() | cell-content-is-time()
2432 //ExtendedTrueCondition ::= ExtendedGetFunction | cell-content-text-length() Operator Value
2433 //TrueCondition ::= GetFunction | cell-content() Operator Value
2434 //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value)
2435 //ExtendedGetFunction ::= cell-content-text-length-is-between(Value, Value) | cell-content-text-length-is-not-between(Value, Value)
2436 //Operator ::= '<' | '>' | '<=' | '>=' | '=' | '!='
2437 //Value ::= NumberValue | String | Formula
2438 //A Formula is a formula without an equals (=) sign at the beginning. See section 8.1.3 for more information.
2439 //A String comprises one or more characters surrounded by quotation marks.
2440 //A NumberValue is a whole or decimal number. It must not contain comma separators for numbers of 1000 or greater.
2441
2442 //ExtendedTrueCondition
2443 if ( valExpression.contains( "cell-content-text-length()" ) )
2444 {
2445 //"cell-content-text-length()>45"
2446 valExpression = valExpression.remove("cell-content-text-length()" );
2447 kdDebug(30518)<<" valExpression = :"<<valExpression<<endl;
2448 val->m_restriction = Restriction::TextLength;
2449
2450 loadOasisValidationCondition( val, valExpression );
2451 }
2452 //cell-content-text-length-is-between(Value, Value) | cell-content-text-length-is-not-between(Value, Value)
2453 else if ( valExpression.contains( "cell-content-text-length-is-between" ) )
2454 {
2455 val->m_restriction = Restriction::TextLength;
2456 val->m_cond = Conditional::Between;
2457 valExpression = valExpression.remove( "cell-content-text-length-is-between(" );
2458 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
2459 valExpression = valExpression.remove( ")" );
2460 TQStringList listVal = TQStringList::split( ",", valExpression );
2461 loadOasisValidationValue( val, listVal );
2462 }
2463 else if ( valExpression.contains( "cell-content-text-length-is-not-between" ) )
2464 {
2465 val->m_restriction = Restriction::TextLength;
2466 val->m_cond = Conditional::Different;
2467 valExpression = valExpression.remove( "cell-content-text-length-is-not-between(" );
2468 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
2469 valExpression = valExpression.remove( ")" );
2470 kdDebug(30518)<<" valExpression :"<<valExpression<<endl;
2471 TQStringList listVal = TQStringList::split( ",", valExpression );
2472 loadOasisValidationValue( val, listVal );
2473
2474 }
2475 //TrueFunction ::= cell-content-is-whole-number() | cell-content-is-decimal-number() | cell-content-is-date() | cell-content-is-time()
2476 else
2477 {
2478 if (valExpression.contains( "cell-content-is-whole-number()" ) )
2479 {
2480 val->m_restriction = Restriction::Number;
2481 valExpression = valExpression.remove( "cell-content-is-whole-number() and " );
2482 }
2483 else if (valExpression.contains( "cell-content-is-decimal-number()" ) )
2484 {
2485 val->m_restriction = Restriction::Integer;
2486 valExpression = valExpression.remove( "cell-content-is-decimal-number() and " );
2487 }
2488 else if (valExpression.contains( "cell-content-is-date()" ) )
2489 {
2490 val->m_restriction = Restriction::Date;
2491 valExpression = valExpression.remove( "cell-content-is-date() and " );
2492 }
2493 else if (valExpression.contains( "cell-content-is-time()" ) )
2494 {
2495 val->m_restriction = Restriction::Time;
2496 valExpression = valExpression.remove( "cell-content-is-time() and " );
2497 }
2498 kdDebug(30518)<<"valExpression :"<<valExpression<<endl;
2499
2500 if ( valExpression.contains( "cell-content()" ) )
2501 {
2502 valExpression = valExpression.remove( "cell-content()" );
2503 loadOasisValidationCondition( val, valExpression );
2504 }
2505 //GetFunction ::= cell-content-is-between(Value, Value) | cell-content-is-not-between(Value, Value)
2506 //for the moment we support just int/double value, not text/date/time :(
2507 if ( valExpression.contains( "cell-content-is-between(" ) )
2508 {
2509 valExpression = valExpression.remove( "cell-content-is-between(" );
2510 valExpression = valExpression.remove( ")" );
2511 TQStringList listVal = TQStringList::split( "," , valExpression );
2512 loadOasisValidationValue( val, listVal );
2513
2514 val->m_cond = Conditional::Between;
2515 }
2516 if ( valExpression.contains( "cell-content-is-not-between(" ) )
2517 {
2518 valExpression = valExpression.remove( "cell-content-is-not-between(" );
2519 valExpression = valExpression.remove( ")" );
2520 TQStringList listVal = TQStringList::split( ",", valExpression );
2521 loadOasisValidationValue( val, listVal );
2522 val->m_cond = Conditional::Different;
2523 }
2524 }
2525 }
2526 if ( element.hasAttributeNS( ooNS::table, "allow-empty-cell" ) )
2527 {
2528 val->allowEmptyCell = ( ( element.attributeNS( ooNS::table, "allow-empty-cell", TQString() )=="true" ) ? true : false );
2529
2530 }
2531 if ( element.hasAttributeNS( ooNS::table, "base-cell-address" ) )
2532 {
2533 //todo what is it ?
2534 }
2535
2536 TQDomElement help = KoDom::namedItemNS( element, ooNS::table, "help-message" );
2537 if ( !help.isNull() )
2538 {
2539 if ( help.hasAttributeNS( ooNS::table, "title" ) )
2540 val->titleInfo = help.attributeNS( ooNS::table, "title", TQString() );
2541 if ( help.hasAttributeNS( ooNS::table, "display" ) )
2542 val->displayValidationInformation = ( ( help.attributeNS( ooNS::table, "display", TQString() )=="true" ) ? true : false );
2543 TQDomElement attrText = KoDom::namedItemNS( help, ooNS::text, "p" );
2544 if ( !attrText.isNull() )
2545 val->messageInfo = attrText.text();
2546 }
2547
2548 TQDomElement error = KoDom::namedItemNS( element, ooNS::table, "error-message" );
2549 if ( !error.isNull() )
2550 {
2551 if ( error.hasAttributeNS( ooNS::table, "title" ) )
2552 val->title = error.attributeNS( ooNS::table, "title", TQString() );
2553 if ( error.hasAttributeNS( ooNS::table, "message-type" ) )
2554 {
2555 TQString str = error.attributeNS( ooNS::table, "message-type", TQString() );
2556 if ( str == "warning" )
2557 val->m_action = Action::Warning;
2558 else if ( str == "information" )
2559 val->m_action = Action::Information;
2560 else if ( str == "stop" )
2561 val->m_action = Action::Stop;
2562 else
2563 kdDebug(30518)<<"validation : message type unknown :"<<str<<endl;
2564 }
2565
2566 if ( error.hasAttributeNS( ooNS::table, "display" ) )
2567 {
2568 kdDebug(30518)<<" display message :"<<error.attributeNS( ooNS::table, "display", TQString() )<<endl;
2569 val->displayMessage = (error.attributeNS( ooNS::table, "display", TQString() )=="true");
2570 }
2571 TQDomElement attrText = KoDom::namedItemNS( error, ooNS::text, "p" );
2572 if ( !attrText.isNull() )
2573 val->message = attrText.text();
2574 }
2575}
2576
2577void OpenCalcImport::loadOasisValidationValue( Validity* val, const TQStringList &listVal )
2578{
2579 bool ok = false;
2580 kdDebug(30518)<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
2581
2582 if ( val->m_restriction == Restriction::Date )
2583 {
2584 val->dateMin = TQDate::fromString( listVal[0] );
2585 val->dateMax = TQDate::fromString( listVal[1] );
2586 }
2587 else if ( val->m_restriction == Restriction::Time )
2588 {
2589 val->timeMin = TQTime::fromString( listVal[0] );
2590 val->timeMax = TQTime::fromString( listVal[1] );
2591 }
2592 else
2593 {
2594 val->valMin = listVal[0].toDouble(&ok);
2595 if ( !ok )
2596 {
2597 val->valMin = listVal[0].toInt(&ok);
2598 if ( !ok )
2599 kdDebug(30518)<<" Try to parse this value :"<<listVal[0]<<endl;
2600
2601#if 0
2602 if ( !ok )
2603 val->valMin = listVal[0];
2604#endif
2605 }
2606 ok=false;
2607 val->valMax = listVal[1].toDouble(&ok);
2608 if ( !ok )
2609 {
2610 val->valMax = listVal[1].toInt(&ok);
2611 if ( !ok )
2612 kdDebug(30518)<<" Try to parse this value :"<<listVal[1]<<endl;
2613
2614#if 0
2615 if ( !ok )
2616 val->valMax = listVal[1];
2617#endif
2618 }
2619 }
2620}
2621
2622
2623void OpenCalcImport::loadOasisValidationCondition( Validity* val,TQString &valExpression )
2624{
2625 TQString value;
2626 if (valExpression.contains( "<=" ) )
2627 {
2628 value = valExpression.remove( "<=" );
2629 val->m_cond = Conditional::InferiorEqual;
2630 }
2631 else if (valExpression.contains( ">=" ) )
2632 {
2633 value = valExpression.remove( ">=" );
2634 val->m_cond = Conditional::SuperiorEqual;
2635 }
2636 else if (valExpression.contains( "!=" ) )
2637 {
2638 //add Differentto attribute
2639 value = valExpression.remove( "!=" );
2640 val->m_cond = Conditional::DifferentTo;
2641 }
2642 else if ( valExpression.contains( "<" ) )
2643 {
2644 value = valExpression.remove( "<" );
2645 val->m_cond = Conditional::Inferior;
2646 }
2647 else if(valExpression.contains( ">" ) )
2648 {
2649 value = valExpression.remove( ">" );
2650 val->m_cond = Conditional::Superior;
2651 }
2652 else if (valExpression.contains( "=" ) )
2653 {
2654 value = valExpression.remove( "=" );
2655 val->m_cond = Conditional::Equal;
2656 }
2657 else
2658 kdDebug(30518)<<" I don't know how to parse it :"<<valExpression<<endl;
2659 kdDebug(30518)<<" value :"<<value<<endl;
2660 if ( val->m_restriction == Restriction::Date )
2661 {
2662 val->dateMin = TQDate::fromString( value );
2663 }
2664 else if ( val->m_restriction == Restriction::Date )
2665 {
2666 val->timeMin = TQTime::fromString( value );
2667 }
2668 else
2669 {
2670 bool ok = false;
2671 val->valMin = value.toDouble(&ok);
2672 if ( !ok )
2673 {
2674 val->valMin = value.toInt(&ok);
2675 if ( !ok )
2676 kdDebug(30518)<<" Try to parse this value :"<<value<<endl;
2677
2678#if 0
2679 if ( !ok )
2680 val->valMin = value;
2681#endif
2682 }
2683 }
2684}
2685
2686
2687int OpenCalcImport::readMetaData()
2688{
2689 int result = 5;
2690 KoDocumentInfo * docInfo = m_doc->documentInfo();
2691 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(docInfo->page( "about" ));
2692 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>(docInfo->page( "author" ));
2693
2694 TQDomNode meta = KoDom::namedItemNS( m_meta, ooNS::office, "document-meta" );
2695 TQDomNode office = KoDom::namedItemNS( meta, ooNS::office, "meta" );
2696
2697 if ( office.isNull() )
2698 return 2;
2699
2700 TQDomElement e = KoDom::namedItemNS( office, ooNS::dc, "creator" );
2701 if ( !e.isNull() && !e.text().isEmpty() )
2702 authorPage->setFullName( e.text() );
2703
2704 e = KoDom::namedItemNS( office, ooNS::dc, "title" );
2705 if ( !e.isNull() && !e.text().isEmpty() )
2706 aboutPage->setTitle( e.text() );
2707
2708 e = KoDom::namedItemNS( office, ooNS::dc, "description" );
2709 if ( !e.isNull() && !e.text().isEmpty() )
2710 aboutPage->setAbstract( e.text() );
2711
2712 e = KoDom::namedItemNS( office, ooNS::dc, "subject" );
2713 if ( !e.isNull() && !e.text().isEmpty() )
2714 aboutPage->setSubject( e.text() );
2715
2716 e= KoDom::namedItemNS( office, ooNS::meta, "keywords" );
2717 if ( !e.isNull() )
2718 {
2719 e = KoDom::namedItemNS( e, ooNS::meta, "keyword" );
2720 if ( !e.isNull() && !e.text().isEmpty() )
2721 aboutPage->setKeywords( e.text() );
2722 }
2723
2724 e = KoDom::namedItemNS( office, ooNS::meta, "document-statistic" );
2725 if ( !e.isNull() && e.hasAttributeNS( ooNS::meta, "table-count" ) )
2726 {
2727 bool ok = false;
2728 result = e.attributeNS( ooNS::meta, "table-count", TQString() ).toInt( &ok );
2729 if ( !ok )
2730 result = 5;
2731 }
2732
2733 m_meta.clear(); // not needed anymore
2734
2735 return result;
2736}
2737
2738KoFilter::ConversionStatus OpenCalcImport::convert( TQCString const & from, TQCString const & to )
2739{
2740 kdDebug(30518) << "Entering OpenCalc Import filter: " << from << " - " << to << endl;
2741
2742 KoDocument * document = m_chain->outputDocument();
2743 if ( !document )
2744 return KoFilter::StupidError;
2745
2746 if ( !::tqt_cast<const KSpread::Doc *>( document ) ) // it's safer that way :)
2747 {
2748 kdWarning(30518) << "document isn't a KSpread::Doc but a " << document->className() << endl;
2749 return KoFilter::NotImplemented;
2750 }
2751
2752 if ( ( from != "application/vnd.sun.xml.calc" && from != "application/vnd.sun.xml.calc.template") || to != "application/x-kspread" )
2753 {
2754 kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl;
2755 return KoFilter::NotImplemented;
2756 }
2757
2758 m_doc = ( Doc * ) document;
2759
2760 if ( m_doc->mimeType() != "application/x-kspread" )
2761 {
2762 kdWarning(30518) << "Invalid document mimetype " << m_doc->mimeType() << endl;
2763 return KoFilter::NotImplemented;
2764 }
2765
2766 kdDebug(30518) << "Opening file " << endl;
2767
2768 KoFilter::ConversionStatus preStatus = openFile();
2769
2770 if ( preStatus != KoFilter::OK )
2771 return preStatus;
2772
2773 emit sigProgress( 13 );
2774 int tables = readMetaData();
2775
2776 emit sigProgress( 15 );
2777
2778 if ( !parseBody( tables ) )
2779 return KoFilter::StupidError;
2780
2781 emit sigProgress( 100 );
2782 return KoFilter::OK;
2783}
2784
2785KoFilter::ConversionStatus OpenCalcImport::openFile()
2786{
2787 KoStore * store = KoStore::createStore( m_chain->inputFile(), KoStore::Read);
2788
2789 kdDebug(30518) << "Store created" << endl;
2790
2791 if ( !store )
2792 {
2793 kdWarning(30518) << "Couldn't open the requested file." << endl;
2794 return KoFilter::FileNotFound;
2795 }
2796
2797 kdDebug(30518) << "Trying to open content.xml" << endl;
2798 TQString messageError;
2799 loadAndParse( m_content, "content.xml", store);
2800 kdDebug(30518) << "Opened" << endl;
2801
2802 TQDomDocument styles;
2803 kdDebug(30518) << "file content.xml loaded " << endl;
2804
2805 loadAndParse( styles, "styles.xml", store);
2806
2807 loadAndParse( m_meta, "meta.xml", store);
2808 loadAndParse( m_settings, "settings.xml", store);
2809
2810 delete store;
2811
2812 emit sigProgress( 10 );
2813
2814 if ( !createStyleMap( styles ) )
2815 return KoFilter::UserCancelled;
2816
2817 return KoFilter::OK;
2818}
2819
2820KoFilter::ConversionStatus OpenCalcImport::loadAndParse( TQDomDocument& doc, const TQString& fileName,KoStore *m_store )
2821{
2822 return OoUtils::loadAndParse( fileName, doc, m_store);
2823}
2824
2825#include "opencalcimport.moc"
2826
This class describe a cell, row or column format.
void setAlign(long a)
setters