lib

KoOasisStyles.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004-2006 David Faure <faure@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17*/
18
19#include "KoOasisStyles.h"
20#include <KoXmlWriter.h>
21#include <kdebug.h>
22#include <tqdom.h>
23#include "KoDom.h"
24#include "KoXmlNS.h"
25#include "KoGenStyles.h"
26#include <tqbuffer.h>
27#include <tdeglobal.h>
28#include <tdelocale.h>
29#include <tqbrush.h>
30#include <KoStyleStack.h>
31
32class KoOasisStyles::Private
33{
34public:
35 // The key of the map is the family
36 TQMap<TQString, TQDict<TQDomElement> > m_styles;
37 TQMap<TQString, TQDict<TQDomElement> > m_stylesAutoStyles;
38};
39
40KoOasisStyles::KoOasisStyles()
41 : d( new Private )
42{
43 m_defaultStyle.setAutoDelete( true );
44 m_masterPages.setAutoDelete( true );
45 m_listStyles.setAutoDelete( true );
46 m_drawStyles.setAutoDelete( true );
47}
48
49KoOasisStyles::~KoOasisStyles()
50{
51 delete d;
52}
53
54void KoOasisStyles::createStyleMap( const TQDomDocument& doc, bool stylesDotXml )
55{
56 const TQDomElement docElement = doc.documentElement();
57 // We used to have the office:version check here, but better let the apps do that
58 TQDomElement fontStyles = KoDom::namedItemNS( docElement, KoXmlNS::office, "font-decls" );
59
60 if ( !fontStyles.isNull() ) {
61 //kdDebug(30003) << "Starting reading in font-decl..." << endl;
62 insertStyles( fontStyles, false );
63 }// else
64 // kdDebug(30003) << "No items found" << endl;
65
66 //kdDebug(30003) << "Starting reading in office:automatic-styles. stylesDotXml=" << stylesDotXml << endl;
67
68 TQDomElement autoStyles = KoDom::namedItemNS( docElement, KoXmlNS::office, "automatic-styles" );
69 if ( !autoStyles.isNull() ) {
70 insertStyles( autoStyles, stylesDotXml );
71 }// else
72 // kdDebug(30003) << "No items found" << endl;
73
74
75 //kdDebug(30003) << "Reading in master styles" << endl;
76
77 TQDomNode masterStyles = KoDom::namedItemNS( docElement, KoXmlNS::office, "master-styles" );
78
79 if ( !masterStyles.isNull() ) {
80 TQDomElement master;
81 forEachElement( master, masterStyles )
82 {
83 if ( master.localName() == "master-page" &&
84 master.namespaceURI() == KoXmlNS::style ) {
85 const TQString name = master.attributeNS( KoXmlNS::style, "name", TQString() );
86 kdDebug(30003) << "Master style: '" << name << "' loaded " << endl;
87 m_masterPages.insert( name, new TQDomElement( master ) );
88 } else
89 // OASIS docu mentions style:handout-master and draw:layer-set here
90 kdWarning(30003) << "Unknown tag " << master.tagName() << " in office:master-styles" << endl;
91 }
92 }
93
94
95 kdDebug(30003) << "Starting reading in office:styles" << endl;
96
97 const TQDomElement officeStyle = KoDom::namedItemNS( docElement, KoXmlNS::office, "styles" );
98
99 if ( !officeStyle.isNull() ) {
100 m_officeStyle = officeStyle;
101 insertOfficeStyles( m_officeStyle );
102
103 }
104
105 //kdDebug(30003) << "Styles read in." << endl;
106}
107
108TQValueVector<TQDomElement> KoOasisStyles::userStyles() const
109{
110 TQValueVector<TQDomElement> vec;
111 // Collect user styles
112 unsigned int i = 0;
113 TQDomElement e;
114 forEachElement( e, m_officeStyle )
115 {
116 if ( e.localName() == "style" &&
117 e.namespaceURI() == KoXmlNS::style )
118 {
119 vec.resize( i+1 );
120 vec[i++] = e;
121 }
122 }
123 return vec;
124}
125
126const TQDict<TQDomElement>& KoOasisStyles::styles(const TQString& family) const
127{
128 // hmm this can create an empty item in the map, but otherwise we couldn't
129 // return a const reference.
130 return d->m_styles[family];
131}
132
133void KoOasisStyles::insertOfficeStyles( const TQDomElement& styles )
134{
135 TQDomElement e;
136 forEachElement( e, styles )
137 {
138 const TQString localName = e.localName();
139 const TQString ns = e.namespaceURI();
140 if ( ( ns == KoXmlNS::svg && (
141 localName == "linearGradient"
142 || localName == "radialGradient" ) )
143 || ( ns == KoXmlNS::draw && (
144 localName == "gradient"
145 || localName == "hatch"
146 || localName == "fill-image"
147 || localName == "marker"
148 || localName == "stroke-dash"
149 || localName == "opacity" ) )
150 )
151 {
152 const TQString name = e.attributeNS( KoXmlNS::draw, "name", TQString() );
153 Q_ASSERT( !name.isEmpty() );
154 TQDomElement* ep = new TQDomElement( e );
155 m_drawStyles.insert( name, ep );
156 }
157 else
158 insertStyle( e, false );
159 }
160}
161
162
163void KoOasisStyles::insertStyles( const TQDomElement& styles, bool styleAutoStyles )
164{
165 //kdDebug(30003) << "Inserting styles from " << styles.tagName() << endl;
166 TQDomElement e;
167 forEachElement( e, styles )
168 insertStyle( e, styleAutoStyles );
169}
170
171void KoOasisStyles::insertStyle( const TQDomElement& e, bool styleAutoStyles )
172{
173 const TQString localName = e.localName();
174 const TQString ns = e.namespaceURI();
175
176 const TQString name = e.attributeNS( KoXmlNS::style, "name", TQString() );
177 if ( ns == KoXmlNS::style && localName == "style" ) {
178 const TQString family = e.attributeNS( KoXmlNS::style, "family", TQString() );
179
180 if ( styleAutoStyles ) {
181 TQDict<TQDomElement>& dict = d->m_stylesAutoStyles[ family ];
182 dict.setAutoDelete( true );
183 if ( dict.find( name ) != 0 )
184 kdDebug(30003) << "Auto-style: '" << name << "' already exists" << endl;
185 dict.insert( name, new TQDomElement( e ) );
186 //kdDebug(30003) << "Style: '" << name << "' loaded as a style auto style" << endl;
187 } else {
188 TQDict<TQDomElement>& dict = d->m_styles[ family ];
189 dict.setAutoDelete( true );
190
191 if ( dict.find( name ) != 0 )
192 kdDebug(30003) << "Style: '" << name << "' already exists" << endl;
193 dict.insert( name, new TQDomElement( e ) );
194 //kdDebug(30003) << "Style: '" << name << "' loaded " << endl;
195 }
196 } else if ( ns == KoXmlNS::style && (
197 localName == "page-layout"
198 || localName == "font-decl"
199 || localName == "presentation-page-layout" ) )
200 {
201 if ( m_styles.find( name ) != 0 )
202 kdDebug(30003) << "Style: '" << name << "' already exists" << endl;
203 m_styles.insert( name, new TQDomElement( e ) );
204 } else if ( localName == "default-style" && ns == KoXmlNS::style ) {
205 const TQString family = e.attributeNS( KoXmlNS::style, "family", TQString() );
206 if ( !family.isEmpty() )
207 m_defaultStyle.insert( family, new TQDomElement( e ) );
208 } else if ( localName == "list-style" && ns == KoXmlNS::text ) {
209 m_listStyles.insert( name, new TQDomElement( e ) );
210 //kdDebug(30003) << "List style: '" << name << "' loaded " << endl;
211 } else if ( ns == KoXmlNS::number && (
212 localName == "number-style"
213 || localName == "currency-style"
214 || localName == "percentage-style"
215 || localName == "boolean-style"
216 || localName == "text-style"
217 || localName == "date-style"
218 || localName == "time-style" ) ) {
219 importDataStyle( e );
220 }
221 // The rest (text:*-configuration and text:outline-style) is to be done by the apps.
222}
223
224// OO spec 2.5.4. p68. Conversion to TQt format: see qdate.html
225// OpenCalcImport::loadFormat has similar code, but slower, intermixed with other stuff,
226// lacking long-textual forms.
227void KoOasisStyles::importDataStyle( const TQDomElement& parent )
228{
229 NumericStyleFormat dataStyle;
230
231 const TQString localName = parent.localName();
232 if (localName == "number-style")
233 dataStyle.type = NumericStyleFormat::Number;
234 else if (localName == "currency-style")
235 dataStyle.type = NumericStyleFormat::Currency;
236 else if (localName == "percentage-style")
237 dataStyle.type = NumericStyleFormat::Percentage;
238 else if (localName == "boolean-style")
239 dataStyle.type = NumericStyleFormat::Boolean;
240 else if (localName == "text-style")
241 dataStyle.type = NumericStyleFormat::Text;
242 else if (localName == "date-style")
243 dataStyle.type = NumericStyleFormat::Date;
244 else if (localName == "time-style")
245 dataStyle.type = NumericStyleFormat::Time;
246
247 TQString format;
248 int precision = -1;
249 int leadingZ = 1;
250 bool thousandsSep = false;
251 //todo negred
252 //bool negRed = false;
253 bool ok = false;
254 int i = 0;
255 TQDomElement e;
256 TQString prefix;
257 TQString suffix;
258 forEachElement( e, parent )
259 {
260 if ( e.namespaceURI() != KoXmlNS::number )
261 continue;
262 TQString localName = e.localName();
263 const TQString numberStyle = e.attributeNS( KoXmlNS::number, "style", TQString() );
264 const bool shortForm = numberStyle == "short" || numberStyle.isEmpty();
265 if ( localName == "day" ) {
266 format += shortForm ? "d" : "dd";
267 } else if ( localName == "day-of-week" ) {
268 format += shortForm ? "ddd" : "dddd";
269 } else if ( localName == "month" ) {
270 if ( e.attributeNS( KoXmlNS::number, "possessive-form", TQString() ) == "true" ) {
271 format += shortForm ? "PPP" : "PPPP";
272 }
273 // TODO the spec has a strange mention of number:format-source
274 else if ( e.attributeNS( KoXmlNS::number, "textual", TQString() ) == "true" ) {
275 format += shortForm ? "MMM" : "MMMM";
276 } else { // month number
277 format += shortForm ? "M" : "MM";
278 }
279 } else if ( localName == "year" ) {
280 format += shortForm ? "yy" : "yyyy";
281 } else if ( localName == "era" ) {
282 //TODO I don't know what is it... (define into oo spec)
283 } else if ( localName == "week-of-year" || localName == "quarter") {
284 // ### not supported in TQt
285 } else if ( localName == "hours" ) {
286 format += shortForm ? "h" : "hh";
287 } else if ( localName == "minutes" ) {
288 format += shortForm ? "m" : "mm";
289 } else if ( localName == "seconds" ) {
290 format += shortForm ? "s" : "ss";
291 } else if ( localName == "am-pm" ) {
292 format += "ap";
293 } else if ( localName == "text" ) { // litteral
294 format += e.text();
295 } else if ( localName == "suffix" ) {
296 suffix = e.text();
297 kdDebug()<<" suffix :"<<suffix<<endl;
298 } else if ( localName == "prefix" ) {
299 prefix = e.text();
300 kdDebug()<<" prefix :"<<prefix<<endl;
301 } else if ( localName == "currency-symbol" ) {
302 dataStyle.currencySymbol = e.text();
303 kdDebug()<<" currency-symbol: "<<dataStyle.currencySymbol<<endl;
304 format += e.text();
305 //TODO
306 // number:language="de" number:country="DE">€</number:currency-symbol>
307 // Stefan: localization of the symbol?
308 } else if ( localName == "number" ) {
309 // TODO: number:grouping="true"
310 if ( e.hasAttributeNS( KoXmlNS::number, "decimal-places" ) )
311 {
312 int d = e.attributeNS( KoXmlNS::number, "decimal-places", TQString() ).toInt( &ok );
313 if ( ok )
314 precision = d;
315 }
316 if ( e.hasAttributeNS( KoXmlNS::number, "min-integer-digits" ) )
317 {
318 int d = e.attributeNS( KoXmlNS::number, "min-integer-digits", TQString() ).toInt( &ok );
319 if ( ok )
320 leadingZ = d;
321 }
322 if ( thousandsSep && leadingZ <= 3 )
323 {
324 format += "#,";
325 for ( i = leadingZ; i <= 3; ++i )
326 format += '#';
327 }
328 for ( i = 1; i <= leadingZ; ++i )
329 {
330 format += '0';
331 if ( ( i % 3 == 0 ) && thousandsSep )
332 format =+ ',' ;
333 }
334 if (precision > -1)
335 {
336 format += '.';
337 for ( i = 0; i < precision; ++i )
338 format += '0';
339 }
340 }
341 else if ( localName == "scientific-number" ) {
342 if (dataStyle.type == NumericStyleFormat::Number)
343 dataStyle.type = NumericStyleFormat::Scientific;
344 int exp = 2;
345
346 if ( e.hasAttributeNS( KoXmlNS::number, "decimal-places" ) )
347 {
348 int d = e.attributeNS( KoXmlNS::number, "decimal-places", TQString() ).toInt( &ok );
349 if ( ok )
350 precision = d;
351 }
352
353 if ( e.hasAttributeNS( KoXmlNS::number, "min-integer-digits" ) )
354 {
355 int d = e.attributeNS( KoXmlNS::number, "min-integer-digits", TQString() ).toInt( &ok );
356 if ( ok )
357 leadingZ = d;
358 }
359
360 if ( e.hasAttributeNS( KoXmlNS::number, "min-exponent-digits" ) )
361 {
362 int d = e.attributeNS( KoXmlNS::number, "min-exponent-digits", TQString() ).toInt( &ok );
363 if ( ok )
364 exp = d;
365 if ( exp <= 0 )
366 exp = 1;
367 }
368
369 if ( thousandsSep && leadingZ <= 3 )
370 {
371 format += "#,";
372 for ( i = leadingZ; i <= 3; ++i )
373 format += '#';
374 }
375
376 for ( i = 1; i <= leadingZ; ++i )
377 {
378 format+='0';
379 if ( ( i % 3 == 0 ) && thousandsSep )
380 format+=',';
381 }
382
383 if (precision > -1)
384 {
385 format += '.';
386 for ( i = 0; i < precision; ++i )
387 format += '0';
388 }
389
390 format+="E+";
391 for ( i = 0; i < exp; ++i )
392 format+='0';
393 } else if ( localName == "fraction" ) {
394 if (dataStyle.type == NumericStyleFormat::Number)
395 dataStyle.type = NumericStyleFormat::Fraction;
396 int integer = 0;
397 int numerator = 1;
398 int denominator = 1;
399 int denominatorValue=0;
400 if ( e.hasAttributeNS( KoXmlNS::number, "min-integer-digits" ) )
401 {
402 int d = e.attributeNS( KoXmlNS::number, "min-integer-digits", TQString() ).toInt( &ok );
403 if ( ok )
404 integer = d;
405 }
406 if ( e.hasAttributeNS( KoXmlNS::number, "min-numerator-digits" ) )
407 {
408 int d = e.attributeNS( KoXmlNS::number, "min-numerator-digits", TQString() ).toInt( &ok );
409 if ( ok )
410 numerator = d;
411 }
412 if ( e.hasAttributeNS( KoXmlNS::number, "min-denominator-digits" ) )
413 {
414 int d = e.attributeNS( KoXmlNS::number, "min-denominator-digits", TQString() ).toInt( &ok );
415 if ( ok )
416 denominator = d;
417 }
418 if ( e.hasAttributeNS( KoXmlNS::number, "denominator-value" ) )
419 {
420 int d = e.attributeNS( KoXmlNS::number, "denominator-value", TQString() ).toInt( &ok );
421 if ( ok )
422 denominatorValue = d;
423 }
424
425 for ( i = 0; i < integer; ++i )
426 format+='#';
427
428 format+=' ';
429
430 for ( i = 0; i < numerator; ++i )
431 format+='?';
432
433 format+='/';
434
435 if ( denominatorValue != 0 )
436 format+=TQString::number( denominatorValue );
437 else
438 {
439 for ( i = 0; i < denominator; ++i )
440 format+='?';
441 }
442 }
443 // Not needed:
444 // <style:map style:condition="value()&gt;=0" style:apply-style-name="N106P0"/>
445 // we handle painting negative numbers in red differently
446
447 }
448
449 const TQString styleName = parent.attributeNS( KoXmlNS::style, "name", TQString() );
450 kdDebug(30003) << "data style: " << styleName << " qt format=" << format << endl;
451 if ( !prefix.isEmpty() )
452 {
453 kdDebug(30003)<<" format.left( prefix.length() ) :"<<format.left( prefix.length() )<<" prefix :"<<prefix<<endl;
454 if ( format.left( prefix.length() )==prefix )
455 {
456 format = format.right( format.length()-prefix.length() );
457 }
458 else
459 prefix = TQString();
460 }
461 if ( !suffix.isEmpty() )
462 {
463 kdDebug(30003)<<"format.right( suffix.length() ) :"<<format.right( suffix.length() )<<" suffix :"<<suffix<<endl;
464 if ( format.right( suffix.length() )==suffix )
465 {
466 format = format.left( format.length()-suffix.length() );
467 }
468 else
469 suffix = TQString();
470 }
471
472 dataStyle.formatStr = format;
473 dataStyle.prefix = prefix;
474 dataStyle.suffix = suffix;
475 dataStyle.precision = precision;
476 kdDebug()<<" finish insert format :"<<format<<" prefix :"<<prefix<<" suffix :"<<suffix<<endl;
477 m_dataFormats.insert( styleName, dataStyle );
478}
479
480#define addTextNumber( text, elementWriter ) { \
481 if ( !text.isEmpty() ) \
482 { \
483 elementWriter.startElement( "number:text" ); \
484 elementWriter.addTextNode( text ); \
485 elementWriter.endElement(); \
486 text=""; \
487 } \
488}
489
490void KoOasisStyles::parseOasisTimeKlocale(KoXmlWriter &elementWriter, TQString & format, TQString & text )
491{
492 kdDebug(30003)<<"parseOasisTimeKlocale(KoXmlWriter &elementWriter, TQString & format, TQString & text ) :"<<format<<endl;
493 do
494 {
495 if ( !saveOasisKlocaleTimeFormat( elementWriter, format, text ) )
496 {
497 text += format[0];
498 format = format.remove( 0, 1 );
499 }
500 }
501 while ( format.length() > 0 );
502 addTextNumber( text, elementWriter );
503}
504
505bool KoOasisStyles::saveOasisKlocaleTimeFormat( KoXmlWriter &elementWriter, TQString & format, TQString & text )
506{
507 bool changed = false;
508 if ( format.startsWith( "%H" ) ) //hh
509 {
510 //hour in 24h
511 addTextNumber( text, elementWriter );
512
513 elementWriter.startElement( "number:hours" );
514 elementWriter.addAttribute( "number:style", "long" );
515 elementWriter.endElement();
516 format = format.remove( 0, 2 );
517 changed = true;
518 }
519 else if ( format.startsWith( "%k" ) )//h
520 {
521 addTextNumber( text, elementWriter );
522
523 elementWriter.startElement( "number:hours" );
524 elementWriter.addAttribute( "number:style", "short" );
525 elementWriter.endElement();
526 format = format.remove( 0, 2 );
527 changed = true;
528 }
529 else if ( format.startsWith( "%I" ) )// ?????
530 {
531 //TODO hour in 12h
532 changed = true;
533 }
534 else if ( format.startsWith( "%l" ) )
535 {
536 //TODO hour in 12h with 1 digit
537 changed = true;
538 }
539 else if ( format.startsWith( "%M" ) )// mm
540 {
541 addTextNumber( text, elementWriter );
542
543 elementWriter.startElement( "number:minutes" );
544 elementWriter.addAttribute( "number:style", "long" );
545 elementWriter.endElement();
546 format = format.remove( 0, 2 );
547 changed = true;
548
549 }
550 else if ( format.startsWith( "%S" ) ) //ss
551 {
552 addTextNumber( text, elementWriter );
553
554 elementWriter.startElement( "number:seconds" );
555 elementWriter.addAttribute( "number:style", "long" );
556 elementWriter.endElement();
557 format = format.remove( 0, 2 );
558 changed = true;
559 }
560 else if ( format.startsWith( "%p" ) )
561 {
562 //TODO am or pm
563 addTextNumber( text, elementWriter );
564
565 elementWriter.startElement( "number:am-pm" );
566 elementWriter.endElement();
567 format = format.remove( 0, 2 );
568 changed = true;
569 }
570 return changed;
571}
572
573
574bool KoOasisStyles::saveOasisTimeFormat( KoXmlWriter &elementWriter, TQString & format, TQString & text, bool &antislash )
575{
576 bool changed = false;
577 //we can also add time to date.
578 if ( antislash )
579 {
580 text+=format[0];
581 format = format.remove( 0, 1 );
582 antislash = false;
583 changed = true;
584 }
585 else if ( format.startsWith( "hh" ) )
586 {
587 addTextNumber( text, elementWriter );
588
589 elementWriter.startElement( "number:hours" );
590 elementWriter.addAttribute( "number:style", "long" );
591 elementWriter.endElement();
592 format = format.remove( 0, 2 );
593 changed = true;
594 }
595 else if ( format.startsWith( "h" ) )
596 {
597 addTextNumber( text, elementWriter );
598
599 elementWriter.startElement( "number:hours" );
600 elementWriter.addAttribute( "number:style", "short" );
601 elementWriter.endElement();
602 format = format.remove( 0, 1 );
603 changed = true;
604 }
605 else if ( format.startsWith( "mm" ) )
606 {
607 addTextNumber( text, elementWriter );
608
609 elementWriter.startElement( "number:minutes" );
610 elementWriter.addAttribute( "number:style", "long" );
611 elementWriter.endElement();
612 format = format.remove( 0, 2 );
613 changed = true;
614 }
615 else if ( format.startsWith( "m" ) )
616 {
617 addTextNumber( text, elementWriter );
618
619 elementWriter.startElement( "number:minutes" );
620 elementWriter.addAttribute( "number:style", "short" );
621 elementWriter.endElement();
622 format = format.remove( 0, 1 );
623 changed = true;
624 }
625 else if ( format.startsWith( "ss" ) )
626 {
627 addTextNumber( text, elementWriter );
628
629 elementWriter.startElement( "number:seconds" );
630 elementWriter.addAttribute( "number:style", "long" );
631 elementWriter.endElement();
632 format = format.remove( 0, 2 );
633 changed = true;
634 }
635 else if ( format.startsWith( "s" ) )
636 {
637 addTextNumber( text, elementWriter );
638
639 elementWriter.startElement( "number:seconds" );
640 elementWriter.addAttribute( "number:style", "short" );
641 elementWriter.endElement();
642 format = format.remove( 0, 1 );
643 changed = true;
644 }
645 else if ( format.startsWith( "ap" ) )
646 {
647 addTextNumber( text, elementWriter );
648
649 elementWriter.startElement( "number:am-pm" );
650 elementWriter.endElement();
651 format = format.remove( 0, 2 );
652 changed = true;
653 }
654 return changed;
655}
656
657TQString KoOasisStyles::saveOasisTimeStyle( KoGenStyles &mainStyles, const TQString & _format, bool klocaleFormat,
658 const TQString & _prefix, const TQString & _suffix )
659{
660 Q_UNUSED(_prefix);
661 Q_UNUSED(_suffix);
662 kdDebug(30003)<<"TQString KoOasisStyles::saveOasisTimeStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
663 TQString format( _format );
664 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_TIME );
665 TQBuffer buffer;
666 buffer.open( IO_WriteOnly );
667 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
668 TQString text;
669 if ( klocaleFormat )
670 {
671 parseOasisTimeKlocale( elementWriter, format, text );
672 }
673 else
674 {
675 bool antislash = false;
676 do
677 {
678 if ( !saveOasisTimeFormat( elementWriter, format, text, antislash ) )
679 {
680 TQString elem( format[0] );
681 format = format.remove( 0, 1 );
682 if ( elem == "\\" )
683 {
684 antislash = true;
685 }
686 else
687 {
688 text += elem;
689 antislash = false;
690 }
691 }
692 }
693 while ( format.length() > 0 );
694 addTextNumber( text, elementWriter );
695 }
696 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
697 currentStyle.addChildElement( "number", elementContents );
698 return mainStyles.lookup( currentStyle, "N" );
699}
700
701//convert klocale string to good format
702void KoOasisStyles::parseOasisDateKlocale(KoXmlWriter &elementWriter, TQString & format, TQString & text )
703{
704 kdDebug(30003)<<"KoOasisStyles::parseOasisDateKlocale(KoXmlWriter &elementWriter, TQString & format, TQString & text ) :"<<format<<endl;
705 do
706 {
707 if ( format.startsWith( "%Y" ) )
708 {
709 addTextNumber( text, elementWriter );
710 elementWriter.startElement( "number:year" );
711 elementWriter.addAttribute( "number:style", "long" );
712 elementWriter.endElement();
713 format = format.remove( 0, 2 );
714 }
715 else if ( format.startsWith( "%y" ) )
716 {
717
718 addTextNumber( text, elementWriter );
719
720 elementWriter.startElement( "number:year" );
721 elementWriter.addAttribute( "number:style", "short" );
722 elementWriter.endElement();
723 format = format.remove( 0, 2 );
724 }
725 else if ( format.startsWith( "%n" ) )
726 {
727 addTextNumber( text, elementWriter );
728 elementWriter.startElement( "number:month" );
729 elementWriter.addAttribute( "number:style", "short" );
730 elementWriter.addAttribute( "number:textual", "false");
731 elementWriter.endElement();
732 format = format.remove( 0, 2 );
733 }
734 else if ( format.startsWith( "%m" ) )
735 {
736 addTextNumber( text, elementWriter );
737 elementWriter.startElement( "number:month" );
738 elementWriter.addAttribute( "number:style", "long" );
739 elementWriter.addAttribute( "number:textual", "false"); //not necessary remove it
740 elementWriter.endElement();
741 format = format.remove( 0, 2 );
742 }
743 else if ( format.startsWith( "%e" ) )
744 {
745 addTextNumber( text, elementWriter );
746
747 elementWriter.startElement( "number:day" );
748 elementWriter.addAttribute( "number:style", "short" );
749 elementWriter.endElement();
750 format = format.remove( 0, 2 );
751 }
752 else if ( format.startsWith( "%d" ) )
753 {
754 addTextNumber( text, elementWriter );
755
756 elementWriter.startElement( "number:day" );
757 elementWriter.addAttribute( "number:style", "long" );
758 elementWriter.endElement();
759 format = format.remove( 0, 2 );
760 }
761 else if ( format.startsWith( "%b" ) )
762 {
763 addTextNumber( text, elementWriter );
764 elementWriter.startElement( "number:month" );
765 elementWriter.addAttribute( "number:style", "short" );
766 elementWriter.addAttribute( "number:textual", "true");
767 elementWriter.endElement();
768 format = format.remove( 0, 2 );
769 }
770 else if ( format.startsWith( "%B" ) )
771 {
772 addTextNumber( text, elementWriter );
773 elementWriter.startElement( "number:month" );
774 elementWriter.addAttribute( "number:style", "long" );
775 elementWriter.addAttribute( "number:textual", "true");
776 elementWriter.endElement();
777 format = format.remove( 0, 2 );
778 }
779 else if ( format.startsWith( "%a" ) )
780 {
781 addTextNumber( text, elementWriter );
782 elementWriter.startElement( "number:day-of-week" );
783 elementWriter.addAttribute( "number:style", "short" );
784 elementWriter.endElement();
785
786 format = format.remove( 0, 2 );
787 }
788 else if ( format.startsWith( "%A" ) )
789 {
790 addTextNumber( text, elementWriter );
791 elementWriter.startElement( "number:day-of-week" );
792 elementWriter.addAttribute( "number:style", "long" );
793 elementWriter.endElement();
794 format = format.remove( 0, 2 );
795 }
796 else
797 {
798 if ( !saveOasisKlocaleTimeFormat( elementWriter, format, text ) )
799 {
800 text += format[0];
801 format = format.remove( 0, 1 );
802 }
803 }
804 }
805 while ( format.length() > 0 );
806 addTextNumber( text, elementWriter );
807}
808
809TQString KoOasisStyles::saveOasisDateStyle( KoGenStyles &mainStyles, const TQString & _format, bool klocaleFormat,
810 const TQString & _prefix, const TQString & _suffix )
811{
812 Q_UNUSED(_prefix);
813 Q_UNUSED(_suffix);
814 kdDebug(30003)<<"TQString KoOasisStyles::saveOasisDateStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
815 TQString format( _format );
816
817 // Not supported into TQt: "era" "week-of-year" "quarter"
818
819 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_DATE );
820 TQBuffer buffer;
821 buffer.open( IO_WriteOnly );
822 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
823 TQString text;
824 if ( klocaleFormat )
825 {
826 parseOasisDateKlocale( elementWriter, format, text );
827 }
828 else
829 {
830 bool antislash = false;
831 do
832 {
833 if ( antislash )
834 {
835 text+=format[0];
836 format = format.remove( 0, 1 );
837 }
838 //TODO implement loading ! What is it ?
839 else if ( format.startsWith( "MMMMM" ) )
840 {
841 addTextNumber( text, elementWriter );
842 elementWriter.startElement( "number:month" );
843 elementWriter.addAttribute( "number:textual", "true");
844 elementWriter.endElement();
845 format = format.remove( 0, 5 );
846 }
847 else if ( format.startsWith( "MMMM" ) )
848 {
849 addTextNumber( text, elementWriter );
850 elementWriter.startElement( "number:month" );
851 elementWriter.addAttribute( "number:style", "long" );
852 elementWriter.addAttribute( "number:textual", "true");
853 elementWriter.endElement();
854 format = format.remove( 0, 4 );
855 }
856 else if ( format.startsWith( "MMM" ) )
857 {
858 addTextNumber( text, elementWriter );
859 elementWriter.startElement( "number:month" );
860 elementWriter.addAttribute( "number:style", "short" );
861 elementWriter.addAttribute( "number:textual", "true");
862 elementWriter.endElement();
863 format = format.remove( 0, 3 );
864 }
865 else if ( format.startsWith( "MM" ) )
866 {
867 addTextNumber( text, elementWriter );
868 elementWriter.startElement( "number:month" );
869 elementWriter.addAttribute( "number:style", "long" );
870 elementWriter.addAttribute( "number:textual", "false"); //not necessary remove it
871 elementWriter.endElement();
872 format = format.remove( 0, 2 );
873 }
874 else if ( format.startsWith( "M" ) )
875 {
876 addTextNumber( text, elementWriter );
877 elementWriter.startElement( "number:month" );
878 elementWriter.addAttribute( "number:style", "short" );
879 elementWriter.addAttribute( "number:textual", "false");
880 elementWriter.endElement();
881 format = format.remove( 0, 1 );
882 }
883 else if ( format.startsWith( "PPPP" ) )
884 {
885 addTextNumber( text, elementWriter );
886 //<number:month number:possessive-form="true" number:textual="true" number:style="long"/>
887 elementWriter.startElement( "number:month" );
888 elementWriter.addAttribute( "number:style", "short" );
889 elementWriter.addAttribute( "number:textual", "false");
890 elementWriter.addAttribute( "number:possessive-form", "true" );
891 elementWriter.endElement();
892 format = format.remove( 0, 4 );
893 }
894 else if ( format.startsWith( "PPP" ) )
895 {
896 addTextNumber( text, elementWriter );
897 //<number:month number:possessive-form="true" number:textual="true" number:style="short"/>
898 elementWriter.startElement( "number:month" );
899 elementWriter.addAttribute( "number:possessive-form", "true" );
900
901 elementWriter.addAttribute( "number:style", "short" );
902 elementWriter.addAttribute( "number:textual", "false");
903 elementWriter.endElement();
904 format = format.remove( 0, 3 );
905 }
906 else if ( format.startsWith( "dddd" ) )
907 {
908 addTextNumber( text, elementWriter );
909
910 elementWriter.startElement( "number:day-of-week" );
911 elementWriter.addAttribute( "number:style", "long" );
912 elementWriter.endElement();
913 format = format.remove( 0, 4 );
914 }
915 else if ( format.startsWith( "ddd" ) )
916 {
917 addTextNumber( text, elementWriter );
918
919 elementWriter.startElement( "number:day-of-week" );
920 elementWriter.addAttribute( "number:style", "short" );
921 elementWriter.endElement();
922 format = format.remove( 0, 3 );
923 }
924 else if ( format.startsWith( "dd" ) )
925 {
926 addTextNumber( text, elementWriter );
927
928 elementWriter.startElement( "number:day" );
929 elementWriter.addAttribute( "number:style", "long" );
930 elementWriter.endElement();
931 format = format.remove( 0, 2 );
932 }
933 else if ( format.startsWith( "d" ) )
934 {
935 addTextNumber( text, elementWriter );
936
937 elementWriter.startElement( "number:day" );
938 elementWriter.addAttribute( "number:style", "short" );
939 elementWriter.endElement();
940 format = format.remove( 0, 1 );
941 }
942 else if ( format.startsWith( "yyyy" ) )
943 {
944 addTextNumber( text, elementWriter );
945
946 elementWriter.startElement( "number:year" );
947 elementWriter.addAttribute( "number:style", "long" );
948 elementWriter.endElement();
949 format = format.remove( 0, 4 );
950 }
951 else if ( format.startsWith( "yy" ) )
952 {
953 addTextNumber( text, elementWriter );
954
955 elementWriter.startElement( "number:year" );
956 elementWriter.addAttribute( "number:style", "short" );
957 elementWriter.endElement();
958 format = format.remove( 0, 2 );
959 }
960 else
961 {
962 if ( !saveOasisTimeFormat( elementWriter, format, text,antislash ) )
963 {
964 TQString elem( format[0] );
965 format = format.remove( 0, 1 );
966 if ( elem == "\\" )
967 {
968 antislash = true;
969 }
970 else
971 {
972 text += elem;
973 antislash = false;
974 }
975 }
976 }
977 }
978 while ( format.length() > 0 );
979 addTextNumber( text, elementWriter );
980 }
981
982 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
983 currentStyle.addChildElement( "number", elementContents );
984 return mainStyles.lookup( currentStyle, "N" );
985}
986
987
988TQString KoOasisStyles::saveOasisFractionStyle( KoGenStyles &mainStyles, const TQString & _format, const TQString &_prefix, const TQString &_suffix )
989{
990 kdDebug(30003)<<"TQString saveOasisFractionStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
991 TQString format( _format );
992
993 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_FRACTION );
994 TQBuffer buffer;
995 buffer.open( IO_WriteOnly );
996 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
997 TQString text;
998 int integer = 0;
999 int numerator = 0;
1000 int denominator = 0;
1001 int denominatorValue = 0;
1002 bool beforeSlash = true;
1003 do
1004 {
1005 if ( format[0]=='#' )
1006 integer++;
1007 else if ( format[0]=='/' )
1008 beforeSlash = false;
1009 else if ( format[0]=='?' )
1010 {
1011 if ( beforeSlash )
1012 numerator++;
1013 else
1014 denominator++;
1015 }
1016 else
1017 {
1018 bool ok;
1019 int value = format.toInt( &ok );
1020 if ( ok )
1021 {
1022 denominatorValue=value;
1023 break;
1024 }
1025 }
1026 format.remove( 0,1 );
1027 }
1028 while ( format.length() > 0 );
1029
1030 text= _prefix;
1031 addTextNumber(text, elementWriter );
1032
1033 elementWriter.startElement( "number:fraction" );
1034 elementWriter.addAttribute( "number:min-integer-digits", integer );
1035 elementWriter.addAttribute( "number:min-numerator-digits",numerator );
1036 elementWriter.addAttribute( "number:min-denominator-digits",denominator );
1037 if ( denominatorValue != 0 )
1038 elementWriter.addAttribute( "number:denominator-value",denominatorValue );
1039 elementWriter.endElement();
1040
1041 addKofficeNumericStyleExtension( elementWriter, _suffix, _prefix );
1042
1043 text=_suffix;
1044 addTextNumber(text, elementWriter );
1045
1046 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
1047 currentStyle.addChildElement( "number", elementContents );
1048 return mainStyles.lookup( currentStyle, "N" );
1049}
1050
1051
1052TQString KoOasisStyles::saveOasisNumberStyle( KoGenStyles &mainStyles, const TQString & _format, const TQString &_prefix, const TQString &_suffix )
1053{
1054 kdDebug(30003)<<"TQString saveOasisNumberStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
1055 TQString format( _format );
1056
1057 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_NUMBER );
1058 TQBuffer buffer;
1059 buffer.open( IO_WriteOnly );
1060 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
1061 TQString text;
1062 int decimalplaces = 0;
1063 int integerdigits = 0;
1064 bool beforeSeparator = true;
1065 do
1066 {
1067 if ( format[0]=='.' || format[0]==',' )
1068 beforeSeparator = false;
1069 else if ( format[0]=='0' && beforeSeparator )
1070 integerdigits++;
1071 else if ( format[0]=='0' && !beforeSeparator )
1072 decimalplaces++;
1073 else
1074 kdDebug(30003)<<" error format 0 \n";
1075 format.remove( 0,1 );
1076 }
1077 while ( format.length() > 0 );
1078 text= _prefix ;
1079 addTextNumber(text, elementWriter );
1080 elementWriter.startElement( "number:number" );
1081 kdDebug(30003)<<" decimalplaces :"<<decimalplaces<<" integerdigits :"<<integerdigits<<endl;
1082 if (!beforeSeparator)
1083 elementWriter.addAttribute( "number:decimal-places", decimalplaces );
1084 elementWriter.addAttribute( "number:min-integer-digits", integerdigits );
1085 elementWriter.endElement();
1086
1087 text =_suffix ;
1088 addTextNumber(text, elementWriter );
1089 addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
1090
1091 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
1092 currentStyle.addChildElement( "number", elementContents );
1093 return mainStyles.lookup( currentStyle, "N" );
1094}
1095
1096TQString KoOasisStyles::saveOasisPercentageStyle( KoGenStyles &mainStyles, const TQString & _format, const TQString &_prefix, const TQString &_suffix )
1097{
1098 //<number:percentage-style style:name="N11">
1099 //<number:number number:decimal-places="2" number:min-integer-digits="1"/>
1100 //<number:text>%</number:text>
1101 //</number:percentage-style>
1102
1103 kdDebug(30003)<<"TQString saveOasisPercentageStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
1104 TQString format( _format );
1105
1106 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_PERCENTAGE );
1107 TQBuffer buffer;
1108 buffer.open( IO_WriteOnly );
1109 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
1110 TQString text;
1111 int decimalplaces = 0;
1112 int integerdigits = 0;
1113 bool beforeSeparator = true;
1114 do
1115 {
1116 if ( format[0]=='.' || format[0]==',' )
1117 beforeSeparator = false;
1118 else if ( format[0]=='0' && beforeSeparator )
1119 integerdigits++;
1120 else if ( format[0]=='0' && !beforeSeparator )
1121 decimalplaces++;
1122 else
1123 kdDebug(30003)<<" error format 0 \n";
1124 format.remove( 0,1 );
1125 }
1126 while ( format.length() > 0 );
1127 text= _prefix ;
1128 addTextNumber(text, elementWriter );
1129 elementWriter.startElement( "number:number" );
1130 if (!beforeSeparator)
1131 elementWriter.addAttribute( "number:decimal-places", decimalplaces );
1132 elementWriter.addAttribute( "number:min-integer-digits", integerdigits );
1133 elementWriter.endElement();
1134
1135 addTextNumber(TQString( "%" ), elementWriter );
1136
1137 text =_suffix ;
1138 addTextNumber(text, elementWriter );
1139 addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
1140
1141 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
1142 currentStyle.addChildElement( "number", elementContents );
1143 return mainStyles.lookup( currentStyle, "N" );
1144
1145}
1146
1147TQString KoOasisStyles::saveOasisScientificStyle( KoGenStyles &mainStyles, const TQString & _format, const TQString &_prefix, const TQString &_suffix )
1148{
1149 //<number:number-style style:name="N60">
1150 //<number:scientific-number number:decimal-places="2" number:min-integer-digits="1" number:min-exponent-digits="3"/>
1151 //</number:number-style>
1152
1153 //example 000,000e+0000
1154 kdDebug(30003)<<"TQString saveOasisScientificStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
1155 TQString format( _format );
1156
1157 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_SCIENTIFIC );
1158 TQBuffer buffer;
1159 buffer.open( IO_WriteOnly );
1160 int decimalplace = 0;
1161 int integerdigits = 0;
1162 int exponentdigits = 0;
1163 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
1164 TQString text;
1165 bool beforeSeparator = true;
1166 bool exponential = false;
1167 bool positive = true;
1168 do
1169 {
1170 if ( !exponential )
1171 {
1172 if ( format[0]=='0' && beforeSeparator )
1173 integerdigits++;
1174 else if ( format[0]==',' || format[0]=='.' )
1175 beforeSeparator = false;
1176 else if ( format[0]=='0' && !beforeSeparator )
1177 decimalplace++;
1178 else if ( format[0].lower()=='e' )
1179 {
1180 format.remove( 0, 1 );
1181 if ( format[0]=='+' )
1182 positive = true;
1183 else if ( format[0]=='-' )
1184 positive = false;
1185 else
1186 kdDebug(30003)<<"Error into scientific number\n";
1187 exponential = true;
1188 }
1189 }
1190 else
1191 {
1192 if ( format[0]=='0' && positive )
1193 exponentdigits++;
1194 else if ( format[0]=='0' && !positive )
1195 exponentdigits--;
1196 else
1197 kdDebug(30003)<<" error into scientific number exponential value\n";
1198 }
1199 format.remove( 0,1 );
1200 }
1201 while ( format.length() > 0 );
1202 text = _prefix ;
1203 addTextNumber(text, elementWriter );
1204
1205 elementWriter.startElement( "number:scientific-number" );
1206 kdDebug(30003)<<" decimalplace :"<<decimalplace<<" integerdigits :"<<integerdigits<<" exponentdigits :"<<exponentdigits<<endl;
1207 if (!beforeSeparator)
1208 elementWriter.addAttribute( "number:decimal-places", decimalplace );
1209 elementWriter.addAttribute( "number:min-integer-digits",integerdigits );
1210 elementWriter.addAttribute( "number:min-exponent-digits",exponentdigits );
1211 elementWriter.endElement();
1212
1213 text = _suffix;
1214 addTextNumber(text, elementWriter );
1215 addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
1216
1217 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
1218 currentStyle.addChildElement( "number", elementContents );
1219 return mainStyles.lookup( currentStyle, "N" );
1220}
1221
1222TQString KoOasisStyles::saveOasisCurrencyStyle( KoGenStyles &mainStyles,
1223 const TQString & _format, const TQString &symbol,
1224 const TQString &_prefix, const TQString &_suffix )
1225{
1226
1227 //<number:currency-style style:name="N107P0" style:volatile="true">
1228 //<number:number number:decimal-places="2" number:min-integer-digits="1" number:grouping="true"/>
1229 //<number:text> </number:text>
1230 //<number:currency-symbol>VEB</number:currency-symbol>
1231 //</number:currency-style>
1232
1233 kdDebug(30003)<<"TQString saveOasisCurrencyStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
1234 TQString format( _format );
1235
1236 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_CURRENCY );
1237 TQBuffer buffer;
1238 buffer.open( IO_WriteOnly );
1239 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
1240 TQString text;
1241 int decimalplaces = 0;
1242 int integerdigits = 0;
1243 bool beforeSeparator = true;
1244 do
1245 {
1246 if ( format[0]=='.' || format[0]==',' )
1247 beforeSeparator = false;
1248 else if ( format[0]=='0' && beforeSeparator )
1249 integerdigits++;
1250 else if ( format[0]=='0' && !beforeSeparator )
1251 decimalplaces++;
1252 else
1253 kdDebug(30003)<<" error format 0 \n";
1254 format.remove( 0,1 );
1255 }
1256 while ( format.length() > 0 );
1257
1258 text = _prefix ;
1259 addTextNumber(text, elementWriter );
1260
1261 elementWriter.startElement( "number:number" );
1262 kdDebug(30003)<<" decimalplaces :"<<decimalplaces<<" integerdigits :"<<integerdigits<<endl;
1263 if (!beforeSeparator)
1264 elementWriter.addAttribute( "number:decimal-places", decimalplaces );
1265 elementWriter.addAttribute( "number:min-integer-digits", integerdigits );
1266 elementWriter.endElement();
1267
1268 text = _suffix ;
1269 addTextNumber(text, elementWriter );
1270 addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
1271
1272 elementWriter.startElement( "number:currency-symbol" );
1273 kdDebug(30003) << " currency-symbol: " << symbol << endl;
1274 elementWriter.addTextNode( symbol.utf8() );
1275 elementWriter.endElement();
1276
1277 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
1278 currentStyle.addChildElement( "number", elementContents );
1279 return mainStyles.lookup( currentStyle, "N" );
1280}
1281
1282TQString KoOasisStyles::saveOasisTextStyle( KoGenStyles &mainStyles, const TQString & _format, const TQString &_prefix, const TQString &_suffix )
1283{
1284
1285 //<number:text-style style:name="N100">
1286 //<number:text-content/>
1288
1289 kdDebug(30003)<<"TQString saveOasisTextStyle( KoGenStyles &mainStyles, const TQString & _format ) :"<<_format<<endl;
1290 TQString format( _format );
1291
1292 KoGenStyle currentStyle( KoGenStyle::STYLE_NUMERIC_TEXT );
1293 TQBuffer buffer;
1294 buffer.open( IO_WriteOnly );
1295 KoXmlWriter elementWriter( &buffer ); // TODO pass indentation level
1296 TQString text;
1297 do
1298 {
1299 format.remove( 0,1 );
1300 }
1301 while ( format.length() > 0 );
1302 text = _prefix ;
1303 addTextNumber(text, elementWriter );
1304
1305 elementWriter.startElement( "number:text-style" );
1306
1307 text = _suffix ;
1308 addTextNumber(text, elementWriter );
1309 addKofficeNumericStyleExtension( elementWriter, _suffix,_prefix );
1310 elementWriter.endElement();
1311
1312 TQString elementContents = TQString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
1313 currentStyle.addChildElement( "number", elementContents );
1314 return mainStyles.lookup( currentStyle, "N" );
1315}
1316
1317//This is an extension of numeric style. For the moment we used namespace of oasis format for specific koffice extention. change it for the futur.
1318void KoOasisStyles::addKofficeNumericStyleExtension( KoXmlWriter & elementWriter, const TQString &_suffix, const TQString &_prefix )
1319 {
1320 if ( !_suffix.isEmpty() )
1321 {
1322 elementWriter.startElement( "number:suffix" );
1323 elementWriter.addTextNode( _suffix );
1324 elementWriter.endElement();
1325 }
1326 if ( !_prefix.isEmpty() )
1327 {
1328 elementWriter.startElement( "number:prefix" );
1329 elementWriter.addTextNode( _prefix );
1330 elementWriter.endElement();
1331 }
1332}
1333
1334void KoOasisStyles::saveOasisFillStyle( KoGenStyle &styleFill, KoGenStyles& mainStyles, const TQBrush & brush )
1335{
1336 if ( brush.style() == TQt::SolidPattern )
1337 {
1338 styleFill.addProperty( "draw:fill","solid" );
1339 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1340 }
1341 else if ( brush.style() == TQt::Dense1Pattern )
1342 {
1343 styleFill.addProperty( "draw:transparency", "94%" );
1344 styleFill.addProperty( "draw:fill","solid" );
1345 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1346 }
1347 else if ( brush.style() == TQt::Dense2Pattern )
1348 {
1349 styleFill.addProperty( "draw:transparency", "88%" );
1350 styleFill.addProperty( "draw:fill","solid" );
1351 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1352 }
1353 else if ( brush.style() == TQt::Dense3Pattern )
1354 {
1355 styleFill.addProperty( "draw:transparency", "63%" );
1356 styleFill.addProperty( "draw:fill","solid" );
1357 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1358 }
1359 else if ( brush.style() == TQt::Dense4Pattern )
1360 {
1361 styleFill.addProperty( "draw:transparency", "50%" );
1362 styleFill.addProperty( "draw:fill","solid" );
1363 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1364 }
1365 else if ( brush.style() == TQt::Dense5Pattern )
1366 {
1367 styleFill.addProperty( "draw:transparency", "37%" );
1368 styleFill.addProperty( "draw:fill","solid" );
1369 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1370 }
1371 else if ( brush.style() == TQt::Dense6Pattern )
1372 {
1373 styleFill.addProperty( "draw:transparency", "12%" );
1374 styleFill.addProperty( "draw:fill","solid" );
1375 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1376 }
1377 else if ( brush.style() == TQt::Dense7Pattern )
1378 {
1379 styleFill.addProperty( "draw:transparency", "6%" );
1380 styleFill.addProperty( "draw:fill","solid" );
1381 styleFill.addProperty( "draw:fill-color", brush.color().name() );
1382 }
1383 else //otherstyle
1384 {
1385 styleFill.addProperty( "draw:fill","hatch" );
1386 styleFill.addProperty( "draw:fill-hatch-name", saveOasisHatchStyle( mainStyles,brush ) );
1387 }
1388
1389}
1390
1391TQString KoOasisStyles::saveOasisHatchStyle( KoGenStyles& mainStyles, const TQBrush &brush )
1392{
1393 KoGenStyle hatchStyle( KoGenStyle::STYLE_HATCH /*no family name*/);
1394 hatchStyle.addAttribute( "draw:color", brush.color().name() );
1395 //hatchStyle.addAttribute( "draw:distance", m_distance ); not implemented into kpresenter
1396 switch( brush.style() )
1397 {
1398 case TQt::HorPattern:
1399 hatchStyle.addAttribute( "draw:style", "single" );
1400 hatchStyle.addAttribute( "draw:rotation", 0);
1401 break;
1402 case TQt::BDiagPattern:
1403 hatchStyle.addAttribute( "draw:style", "single" );
1404 hatchStyle.addAttribute( "draw:rotation", 450);
1405 break;
1406 case TQt::VerPattern:
1407 hatchStyle.addAttribute( "draw:style", "single" );
1408 hatchStyle.addAttribute( "draw:rotation", 900);
1409 break;
1410 case TQt::FDiagPattern:
1411 hatchStyle.addAttribute( "draw:style", "single" );
1412 hatchStyle.addAttribute( "draw:rotation", 1350);
1413 break;
1414 case TQt::CrossPattern:
1415 hatchStyle.addAttribute( "draw:style", "double" );
1416 hatchStyle.addAttribute( "draw:rotation", 0);
1417 break;
1418 case TQt::DiagCrossPattern:
1419 hatchStyle.addAttribute( "draw:style", "double" );
1420 hatchStyle.addAttribute( "draw:rotation", 450);
1421 break;
1422 default:
1423 break;
1424 }
1425
1426 return mainStyles.lookup( hatchStyle, "hatch" );
1427}
1428
1429TQBrush KoOasisStyles::loadOasisFillStyle( const KoStyleStack &styleStack, const TQString & fill, const KoOasisStyles & oasisStyles )
1430{
1431 TQBrush tmpBrush;
1432 if ( fill == "solid" )
1433 {
1434 tmpBrush.setStyle(static_cast<TQt::BrushStyle>( 1 ) );
1435 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "fill-color" ) )
1436 tmpBrush.setColor(styleStack.attributeNS( KoXmlNS::draw, "fill-color" ) );
1437 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "transparency" ) )
1438 {
1439 TQString transparency = styleStack.attributeNS( KoXmlNS::draw, "transparency" );
1440 if ( transparency == "94%" )
1441 {
1442 tmpBrush.setStyle(TQt::Dense1Pattern);
1443 }
1444 else if ( transparency == "88%" )
1445 {
1446 tmpBrush.setStyle(TQt::Dense2Pattern);
1447 }
1448 else if ( transparency == "63%" )
1449 {
1450 tmpBrush.setStyle(TQt::Dense3Pattern);
1451
1452 }
1453 else if ( transparency == "50%" )
1454 {
1455 tmpBrush.setStyle(TQt::Dense4Pattern);
1456
1457 }
1458 else if ( transparency == "37%" )
1459 {
1460 tmpBrush.setStyle(TQt::Dense5Pattern);
1461
1462 }
1463 else if ( transparency == "12%" )
1464 {
1465 tmpBrush.setStyle(TQt::Dense6Pattern);
1466
1467 }
1468 else if ( transparency == "6%" )
1469 {
1470 tmpBrush.setStyle(TQt::Dense7Pattern);
1471
1472 }
1473 else
1474 kdDebug()<<" transparency is not defined into kpresenter :"<<transparency<<endl;
1475 }
1476 }
1477 else if ( fill == "hatch" )
1478 {
1479 TQString style = styleStack.attributeNS( KoXmlNS::draw, "fill-hatch-name" );
1480 kdDebug()<<" hatch style is : "<<style<<endl;
1481
1482 //type not defined by default
1483 //try to use style.
1484 TQDomElement* draw = oasisStyles.drawStyles()[style];
1485 if ( draw)
1486 {
1487 kdDebug()<<"We have a style\n";
1488 int angle = 0;
1489 if( draw->hasAttributeNS( KoXmlNS::draw, "rotation" ))
1490 {
1491 angle = (draw->attributeNS( KoXmlNS::draw, "rotation", TQString() ).toInt())/10;
1492 kdDebug()<<"angle :"<<angle<<endl;
1493 }
1494 if(draw->hasAttributeNS( KoXmlNS::draw, "color" ) )
1495 {
1496 //kdDebug()<<" draw:color :"<<draw->attributeNS( KoXmlNS::draw, "color", TQString() )<<endl;
1497 tmpBrush.setColor(draw->attributeNS( KoXmlNS::draw, "color", TQString() ) );
1498 }
1499 if( draw->hasAttributeNS( KoXmlNS::draw, "distance" ))
1500 {
1501 //todo implemente it into kpresenter
1502 }
1503 if( draw->hasAttributeNS( KoXmlNS::draw, "display-name"))
1504 {
1505 //todo implement it into kpresenter
1506 }
1507 if( draw->hasAttributeNS( KoXmlNS::draw, "style" ))
1508 {
1509 //todo implemente it into kpresenter
1510 TQString styleHash = draw->attributeNS( KoXmlNS::draw, "style", TQString() );
1511 if( styleHash == "single")
1512 {
1513 switch( angle )
1514 {
1515 case 0:
1516 case 180:
1517 tmpBrush.setStyle(TQt::HorPattern );
1518 break;
1519 case 45:
1520 case 225:
1521 tmpBrush.setStyle(TQt::BDiagPattern );
1522 break;
1523 case 90:
1524 case 270:
1525 tmpBrush.setStyle(TQt::VerPattern );
1526 break;
1527 case 135:
1528 case 315:
1529 tmpBrush.setStyle(TQt::FDiagPattern );
1530 break;
1531 default:
1532 //todo fixme when we will have a kopaint
1533 kdDebug()<<" draw:rotation 'angle' : "<<angle<<endl;
1534 break;
1535 }
1536 }
1537 else if( styleHash == "double")
1538 {
1539 switch( angle )
1540 {
1541 case 0:
1542 case 180:
1543 case 90:
1544 case 270:
1545 tmpBrush.setStyle(TQt::CrossPattern );
1546 break;
1547 case 45:
1548 case 135:
1549 case 225:
1550 case 315:
1551 tmpBrush.setStyle(TQt::DiagCrossPattern );
1552 break;
1553 default:
1554 //todo fixme when we will have a kopaint
1555 kdDebug()<<" draw:rotation 'angle' : "<<angle<<endl;
1556 break;
1557 }
1558
1559 }
1560 else if( styleHash == "triple")
1561 {
1562 kdDebug()<<" it is not implemented :( \n";
1563 }
1564 }
1565 }
1566 }
1567 return tmpBrush;
1568}
1569
1570const TQDomElement* KoOasisStyles::defaultStyle( const TQString& family ) const
1571{
1572 return m_defaultStyle[family];
1573}
1574
1575const TQDomElement* KoOasisStyles::findStyle( const TQString& name ) const
1576{
1577 return m_styles[ name ];
1578}
1579
1580const TQDomElement* KoOasisStyles::findStyle( const TQString& styleName, const TQString& family ) const
1581{
1582 const TQDomElement* style = d->m_styles[ family ][ styleName ];
1583 if ( style && !family.isEmpty() ) {
1584 const TQString styleFamily = style->attributeNS( KoXmlNS::style, "family", TQString() );
1585 if ( styleFamily != family ) {
1586 kdWarning() << "KoOasisStyles: was looking for style " << styleName
1587 << " in family " << family << " but got " << styleFamily << endl;
1588 }
1589 }
1590 return style;
1591}
1592
1593const TQDomElement* KoOasisStyles::findStyleAutoStyle( const TQString& styleName, const TQString& family ) const
1594{
1595 const TQDomElement* style = d->m_stylesAutoStyles[ family ][ styleName ];
1596 if ( style ) {
1597 const TQString styleFamily = style->attributeNS( KoXmlNS::style, "family", TQString() );
1598 if ( styleFamily != family ) {
1599 kdWarning() << "KoOasisStyles: was looking for style " << styleName
1600 << " in family " << family << " but got " << styleFamily << endl;
1601 }
1602 }
1603 return style;
1604}
A generic style, i.e.
void addChildElement(const TQString &elementName, const TQString &elementContents)
Add a child element to the style properties.
void addProperty(const TQString &propName, const TQString &propValue, PropertyType type=DefaultType)
Add a property to the style.
Repository of styles used during saving of OASIS/OOo file.
Definition KoGenStyles.h:60
TQString lookup(const KoGenStyle &style, const TQString &name=TQString(), int flags=NoFlag)
Look up a style in the collection, inserting it if necessary.
Repository of styles used during loading of OASIS/OOo file.
const TQDict< TQDomElement > & drawStyles() const
static TQString saveOasisTextStyle(KoGenStyles &mainStyles, const TQString &_format, const TQString &_prefix=TQString(), const TQString &_suffix=TQString())
const TQDomElement & officeStyle() const
TQValueVector< TQDomElement > userStyles() const
const TQDict< TQDomElement > & styles(const TQString &family) const
const TQDomElement * findStyleAutoStyle(const TQString &name, const TQString &family) const
Similar to findStyle but for auto-styles in styles.xml only.
const TQDomElement * findStyle(const TQString &name) const
Look up a style by name.
void createStyleMap(const TQDomDocument &doc, bool stylesDotXml)
Look into doc for styles and remember them.
const TQDomElement * defaultStyle(const TQString &family) const
This class implements a stack for the different styles of an object.
bool hasAttributeNS(const char *nsURI, const char *localName, const char *detail=0) const
Check if any of the styles on the stack has an attribute called 'name'-'detail' where detail is e....
TQString attributeNS(const char *nsURI, const char *localName, const char *detail=0) const
Search for the attribute called 'name', starting on top of the stack, and return it.
A class for writing out XML (to any TQIODevice), with a special attention on performance.
Definition KoXmlWriter.h:37
void startElement(const char *tagName, bool indentInside=true)
Start a new element, as a child of the current element.
void addTextNode(const TQString &str)
Overloaded version of addTextNode( const char* ), which is a bit slower because it needs to convert s...
void endElement()
Terminate the current element.
void addAttribute(const char *attrName, const TQString &value)
Overloaded version of addAttribute( const char*, const char* ), which is a bit slower because it need...
Definition KoXmlWriter.h:76
const char * name(StdAction id)
KOFFICECORE_EXPORT TQDomElement namedItemNS(const TQDomNode &node, const char *nsURI, const char *localName)
A namespace-aware version of TQDomNode::namedItem(), which also takes care of casting to a TQDomEleme...
Definition KoDom.cpp:22
Prefix and suffix are always included into formatStr.