bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww1 / w1filter.cxx
blobc2483488e24cec89e779867cb2c7ff52028c49dc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <tools/solar.h>
23 #include <comphelper/string.hxx>
24 #include <editeng/paperinf.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <vcl/graph.hxx>
27 #include <vcl/wmf.hxx>
28 #include <editeng/fontitem.hxx>
29 #include <editeng/lrspitem.hxx>
30 #include <editeng/ulspitem.hxx>
31 #include <editeng/wghtitem.hxx>
32 #include <editeng/postitem.hxx>
33 #include <editeng/crossedoutitem.hxx>
34 #include <editeng/contouritem.hxx>
35 #include <editeng/cmapitem.hxx>
36 #include <editeng/fhgtitem.hxx>
37 #include <editeng/udlnitem.hxx>
38 #include <editeng/wrlmitem.hxx>
39 #include <editeng/colritem.hxx>
40 #include <editeng/kernitem.hxx>
41 #include <editeng/escapementitem.hxx>
42 #include <editeng/tstpitem.hxx>
43 #include <svl/urihelper.hxx>
44 #include <fmtfsize.hxx>
45 #include <doc.hxx>
46 #include <pam.hxx>
47 #include <ndtxt.hxx>
48 #include <pagedesc.hxx>
49 #include <flddat.hxx>
50 #include <reffld.hxx>
51 #include <expfld.hxx>
52 #include <docufld.hxx>
53 #include <ftninfo.hxx>
54 #include <section.hxx> // class SwSection
55 #include <fltini.hxx>
56 #include <w1par.hxx>
58 #include <docsh.hxx>
59 #include <swerror.h>
60 #include <mdiexp.hxx>
61 #include <statstr.hrc>
62 #if OSL_DEBUG_LEVEL > 0
63 #include <stdio.h>
64 #endif
66 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
67 #include <com/sun/star/document/XDocumentProperties.hpp>
69 #define MAX_FIELDLEN 64000
71 using namespace css;
72 using namespace nsSwDocInfoSubType;
75 ///////////////////////////////////////////////////////////////////////
77 // hier stehen die methoden operator<<, Out, Start und Stop mit
78 // folgender Bedeutung: wenn moeglich wird die information aus dem
79 // dokument per
80 // operator<<()
81 // in die shell uebertragen. sind jedoch weitere parameter noetig
82 // wurde der name
83 // Out()
84 // gewaehlt. ist ein bereich zu kennzeichnen (zB bei attributen
85 // von/bis), heissen die methoden
86 // Start(), Stop()
87 // alle diese methoden stehen in diesem modul, das fuer den filter,
88 // jedoch nicht fuer den dumper noetig ist. und da alle regeln ihre
89 // ausnahme haben: hier stehen auch methoden, die aus anderen gruenden
90 // fuer den dumper sinnlos sind, zB wenn sie auf sv-strukturen beruhen
91 // wie zB GetFont() auf SvxFontItem.
94 /////////////////////////////////////////////////////////////// Manager
95 Ww1Shell& operator <<(Ww1Shell& rOut, Ww1Manager& This)
97 // verhindern, das bei rekusivem aufruf dies mehrfach passiert:
98 if (!This.Pushed())
100 { // der wird nur temporaer gebraucht:
101 This.SetInStyle( true );
102 Ww1StyleSheet(This.aFib).Out(rOut, This);
103 This.SetInStyle( false );
105 { // dieser auch:
106 Ww1Assoc(This.aFib).Out(rOut);
108 // dieser nicht, der ist bereits member:
109 This.aDop.Out(rOut);
110 // Jetzt entscheiden, wie Seitenvorlagen erzeugt werden
111 if (This.GetSep().Count() <= 1)
112 rOut.SetUseStdPageDesc();
114 // und jetzt das eigentliche dok:
115 sal_Unicode cUnknown = ' ';
116 while (*This.pSeek < This.pDoc->Count())
118 // ausgabe des ProgressState nur, wenn im haupttext, da sonst
119 // nicht bestimmt werden kann, wie weit wir sind:
120 if (!This.Pushed())
121 ::SetProgressState(This.Where() * 100 / This.pDoc->Count(),
122 rOut.GetDoc().GetDocShell());
123 // hier werden abwechselnd die attribute und die zeichen in die
124 // shell gepumpt. die positionen werden durch das lesen der
125 // zeichen aus dem manager hoch- gezaehlt. erst alle attribute:
126 This.Out(rOut, cUnknown);
127 // das textdocument pDoc ist ein Ww1PlainText, dessen Out()
128 // methode solange ausgibt, bis entweder ein sonderzeichen
129 // auftaucht oder die anzahl der auszugebenden zeichen erreicht
130 // ist:
131 cUnknown = This.pDoc->Out(rOut, *This.pSeek);
133 This.SetStopAll(true);
134 This.OutStop(rOut, cUnknown); // Damit die Attribute am Ende geschlossen
135 This.SetStopAll(false); // werden
136 return rOut;
139 void Ww1Manager::OutStop(Ww1Shell& rOut, sal_Unicode cUnknown)
141 // Bookmarks brauchen nicht beendet werden ???
142 if (pFld)
143 pFld->Stop(rOut, *this, cUnknown);
144 if (!Pushed())
145 aFtn.Stop(rOut, *this, cUnknown);
146 if (1)
147 aChp.Stop(rOut, *this, cUnknown);
148 if (1)
149 aPap.Stop(rOut, *this, cUnknown);
150 if (!Pushed())
151 aSep.Stop(rOut, *this, cUnknown);
154 void Ww1Manager::OutStart( Ww1Shell& rOut )
156 // alle attribute, die's brauchen beginnen
157 if (!Pushed())
158 aSep.Start(rOut, *this);
159 if (1)
160 aPap.Start(rOut, *this);
161 if (1)
162 aChp.Start(rOut, *this);
163 if (!Pushed())
164 aFtn.Start(rOut, *this);
165 if (pFld)
166 pFld->Start(rOut, *this);
167 if (!Pushed())
168 aBooks.Start(rOut, *this);
169 // bestimmen, wo das naechste Ereigniss ist:
170 sal_uLong ulEnd = pDoc->Count(); // spaetestens am textende
171 if (!Pushed())
172 if (ulEnd > aSep.Where()) // naechster Sep vorher?
173 ulEnd = aSep.Where();
174 if (1)
175 if (ulEnd > aPap.Where()) // naechster Pap vorher?
176 ulEnd = aPap.Where();
177 if (1)
178 if (ulEnd > aChp.Where()) // naechster Chp vorher?
179 ulEnd = aChp.Where();
180 if (!Pushed())
181 if (ulEnd > aFtn.Where()) // naechster Ftn vorher?
182 ulEnd = aFtn.Where();
183 if (pFld)
184 if (ulEnd > pFld->Where()) // naechster Fld vorher?
185 ulEnd = pFld->Where();
186 if (!Pushed())
187 if (ulEnd > aBooks.Where()) // naechster Bookmark vorher?
188 ulEnd = aBooks.Where();
189 *pSeek = Where(); // momentane position
190 if (*pSeek < ulEnd) // sind wir bereits weiter?
191 *pSeek = ulEnd;
194 void Ww1Manager::Out(Ww1Shell& rOut, sal_Unicode cUnknown)
196 // Je nach modus wird hier mit feldern, fusznoten, zeichenattributen,
197 // absatzatributen und sektionen wie folgt verfahren: von allen wird
198 // zuallererst die stop-methoden gerufen. stellt das objekt fest, dasz
199 // etwas zu beenden ist (natuerlich nicht im ersten durchgang) beendet
200 // es dies, ansonsten ist der aufruf wirkungslos. dann werden
201 // unbehandelte sonderzeichen augegeben. das werden genauso alle
202 // start-methoden gerufen und danach per where festgestellt, an
203 // welcher stelle die naechste aktion zu erwarten ist.
205 // ist der manager in einem ge'push'ten mode, werden bestimmte
206 // elemente ausgeklammert. felder werden wiederum nur in besonderen
207 // faellen augeklammert, wenn naemlich bereiche ausgegeben werden, die
208 // keine felder enthalten koennen. charakterattribute und
209 // paragraphenattribute werden jedoch nie ausgeklammert. die if (1)
210 // wurden zur verdeutlichung der einheitlichkeit eingefuegt.
212 // Erstmal eine Sonderbehandlung fuer Tabellen:
213 // die wichtigen Attribute lassen sich am Besten vor Beendigung derselben
214 // abfragen.
215 // Optimierung: Sie werden nur auf sinnvolle Werte gesetzt, wenn
216 // das 0x07-Zeiche ansteht.
218 bool bLIsTtp = false;
219 sal_Bool bLHasTtp = sal_False;
220 if( cUnknown == 0x07 )
222 bLIsTtp = IsInTtp();
223 bLHasTtp = HasTtp();
226 OutStop( rOut, cUnknown ); // Attrs ggfs. beenden
228 // meta-zeichen interpretieren:
229 if (!Ww1PlainText::IsChar(cUnknown))
230 switch (cUnknown)
232 case 0x02:
233 // dontknow
234 break;
235 case 0x07: // table
236 if (rOut.IsInTable() && HasInTable() && !bLIsTtp && !bLHasTtp)
237 rOut.NextTableCell();
238 break;
239 case 0x09: // tab
240 rOut.NextTab();
241 break;
242 case 0x0a: // linefeed
243 rOut.NextParagraph();
244 break;
245 case 0x0b: // linebreak
246 if (rOut.IsInTable())
248 else
249 rOut.NextLine();
250 break;
251 case 0x0d: // carriage return
252 // ignore
253 break;
254 case 0x0c: // pagebreak
255 rOut.NextPage();
256 break;
257 case 0x14: // sectionendchar
258 // ignore here
259 break;
260 default:
261 break;
264 OutStart( rOut ); // Attrs ggfs. starten und Naechste Pos berechnen
267 SvxFontItem Ww1Manager::GetFont(sal_uInt16 nFCode)
269 return aFonts.GetFont(nFCode);
272 void Ww1Manager::Push0(Ww1PlainText* _pDoc, sal_uLong ulSeek, Ww1Fields* _pFld)
274 OSL_ENSURE(!Pushed(), "Ww1Manager");
275 this->pDoc = _pDoc;
276 pSeek = new sal_uLong;
277 *pSeek = pDoc->Where();
278 aPap.Push(ulSeek);
279 aChp.Push(ulSeek);
280 this->pFld = _pFld;
283 // ulSeek ist der FC-Abstand zwischen Hauptest-Start und Sondertext-Start
284 // ulSeek2 ist der Offset dieses bestimmten Sondertextes im Sondertext-Bereich,
285 // also z.B. der Offset des speziellen K/F-Textes
286 void Ww1Manager::Push1(Ww1PlainText* _pDoc, sal_uLong ulSeek, sal_uLong ulSeek2,
287 Ww1Fields* _pFld)
289 OSL_ENSURE(!Pushed(), "Ww1Manager");
290 this->pDoc = _pDoc;
291 pSeek = new sal_uLong;
292 *pSeek = pDoc->Where();
293 aPap.Push(ulSeek + ulSeek2);
294 aChp.Push(ulSeek + ulSeek2);
295 if( _pFld )
296 _pFld->Seek( ulSeek2 );
297 this->pFld = _pFld;
300 void Ww1Manager::Pop()
302 OSL_ENSURE(Pushed(), "Ww1Manager");
303 delete pDoc;
304 pDoc = &aDoc;
305 delete pSeek;
306 pSeek = &ulDocSeek;
307 aChp.Pop();
308 aPap.Pop();
309 delete pFld;
310 pFld = &aFld;
313 ///////////////////////////////////////////////////////////// Bookmarks
315 void Ww1Bookmarks::Out(Ww1Shell& rOut, Ww1Manager& rMan, sal_uInt16)
317 if (GetIsEnd())
319 rOut.SetBookEnd(GetHandle());
320 return;
323 const String & rName = GetName();
324 if( rName.EqualsAscii( "_Toc", 0, 4 ) ) // "_Toc*" ist ueberfluessig
325 return;
327 if( rOut.IsFlagSet( SwFltControlStack::HYPO )
328 && rName.EqualsIgnoreCaseAscii( "FORMULAR" ) )
329 rOut.SetProtect();
331 // Fuer UEbersetzung Bookmark -> Variable setzen
332 long nLen = Len();
333 if( nLen > MAX_FIELDLEN )
334 nLen = MAX_FIELDLEN;
336 // Lese Inhalt des Bookmark
337 // geht vermulich auch ueber Ww1PlainText
338 String aVal( rMan.GetText().GetText( Where(), nLen ) );
340 // in 2 Schritten, da OS/2 zu doof ist
341 SwFltBookmark aBook( rName, aVal, GetHandle(), sal_False );
342 rOut << aBook;
345 void Ww1Bookmarks::Start(Ww1Shell& rOut, Ww1Manager& rMan)
347 if (rMan.Where() >= Where())
349 Out(rOut, rMan);
350 ++(*this);
354 ///////////////////////////////////////////////////////////// Footnotes
355 void Ww1Footnotes::Start(Ww1Shell& rOut, Ww1Manager& rMan)
357 if (rMan.Where() >= Where())
359 OSL_ENSURE(nPlcIndex < Count(), "WwFootnotes");
360 sal_Unicode c;
361 rMan.Fill(c);
362 OSL_ENSURE(c==0x02, "Ww1Footnotes");
363 if (c==0x02)
365 Ww1FtnText* pText = new Ww1FtnText(rMan.GetFib());
366 // beginn des textes dieser fusznote:
367 sal_uLong start = aText.Where(nPlcIndex);
368 pText->Seek(start);
369 // laenge des textes
370 sal_uLong count = aText.Where(nPlcIndex+1) - start;
371 pText->SetCount(count);
372 // fusznotenkennung sollte das erste byte sein
373 pText->Out(c);
374 OSL_ENSURE(c==0x02, "Ww1Footnotes");
375 count--; // fuer das eben gelesene kenn-byte
376 // fusznoten mode beginnen:
377 rOut.BeginFootnote();
378 bStarted = sal_True;
379 rMan.Push0(pText, pText->Offset(rMan.GetFib()),
380 new Ww1FootnoteFields(rMan.GetFib()));
381 rOut << rMan;
382 rMan.Pop();
383 rOut.EndFootnote();
385 else
386 ++(*this);
390 void Ww1Footnotes::Stop(Ww1Shell& /*rOut*/, Ww1Manager& rMan, sal_Unicode& c)
392 if (bStarted && rMan.Where() > Where())
394 OSL_ENSURE(nPlcIndex < Count(), "Ww1Footnotes");
395 c = ' ';
396 ++(*this);
400 //////////////////////////////////////////////////////////////// Fields
401 void Ww1Fields::Start(Ww1Shell& rOut, Ww1Manager& rMan)
403 if (rMan.Where() >= Where()){
404 OSL_ENSURE(nPlcIndex < Count(), "Ww1Fields");
405 if (GetData()->chGet() == 19)
406 Out(rOut, rMan);
407 else
408 ++(*this); // ignore
412 void Ww1Fields::Stop( Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode& c)
414 if (rMan.Where() >= Where())
416 OSL_ENSURE(nPlcIndex < Count(), "Ww1Fields");
417 if (GetData()->chGet() != 19)
419 rMan.Fill( c );
420 OSL_ENSURE(c==21, "Ww1Fields");
421 ++(*this);
422 c = ' ';
423 if (pField)
424 // haben wir ein fertiges feld da, das eingefuegt werden soll?
426 rOut << *pField;
427 delete pField;
428 pField = 0;
429 // das macht der filter so, damit attribute die ueber das feld
430 // gelten auch wirklich eingelesen werden und dem feld
431 // zugeordnet werden.
433 if (sErgebnis.Len())
434 rOut << sErgebnis;
439 enum WWDateTime{ WW_DONTKNOW = 0x0, WW_DATE = 0x1, WW_TIME = 0x2, WW_BOTH = 0x3 };
441 static WWDateTime GetTimeDatePara( const String& rForm,
442 SwTimeFormat* pTime = 0,
443 SwDateFormat* pDate = 0 )
445 WWDateTime eDT = WW_BOTH;
446 if( STRING_NOTFOUND == rForm.Search( 'H' )) // H -> 24h
448 if( pTime )
449 *pTime = TF_SSMM_24;
451 else if( STRING_NOTFOUND == rForm.Search( 'H' )) // h -> 24h
453 if( pTime )
454 *pTime = TF_SSMM_12;
456 else // keine Zeit
458 eDT = (WWDateTime)( eDT & ~(sal_uInt16)WW_TIME );
461 xub_StrLen nDPos = 0;
462 while( STRING_NOTFOUND != nDPos )
464 nDPos = rForm.Search( 'M', nDPos ); // M -> Datum
465 if( !nDPos )
466 break;
467 sal_Unicode cPrev = rForm.GetChar( nDPos - 1 );
468 // ignoriere dabei "AM", "aM", "PM", "pM"
469 if( 'a' != cPrev && 'A' != cPrev && 'p' != cPrev && 'P' != cPrev )
470 break;
471 // else search again
472 ++nDPos;
475 if( STRING_NOTFOUND != nDPos ) // Monat -> Datum ?
477 static SwDateFormat const aDateA[32] =
479 DFF_DMY, DFF_DMMY, DFF_DMYY, DFF_DMMYY,
480 DFF_DMMMY, DFF_DMMMY, DFF_DMMMYY, DFF_DMMMYY,
481 DFF_DDMMY, DFF_DDMMY, DFF_DDMMMYY, DFF_DDMMMYY,
482 DFF_DDMMMY, DFF_DDMMMY, DFF_DDMMMYY, DFF_DDMMMYY,
483 DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY,
484 DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY,
485 DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY,
486 DFF_DDDMMMY, DFF_DDDMMMY, DFF_DDDMMMYY, DFF_DDDMMMYY
489 bool bHasDay = STRING_NOTFOUND != rForm.Search( 't' ) ||
490 STRING_NOTFOUND != rForm.Search( 'T' ) ||
491 STRING_NOTFOUND != rForm.Search( 'd' ) ||
492 STRING_NOTFOUND != rForm.Search( 'D' );
494 sal_Bool bLongDayOfWeek= STRING_NOTFOUND != rForm.SearchAscii( "tttt" ) ||
495 STRING_NOTFOUND != rForm.SearchAscii( "TTTT" ) ||
496 STRING_NOTFOUND != rForm.SearchAscii( "dddd" ) ||
497 STRING_NOTFOUND != rForm.SearchAscii( "DDDD" );
499 sal_Bool bDayOfWeek = STRING_NOTFOUND != rForm.SearchAscii( "ttt" ) ||
500 STRING_NOTFOUND != rForm.SearchAscii( "TTT" ) ||
501 STRING_NOTFOUND != rForm.SearchAscii( "ddd" ) ||
502 STRING_NOTFOUND != rForm.SearchAscii( "DDD" );
504 // M, MM -> numeric month
505 // MMM, MMMM -> text. month
506 sal_Bool bLitMonth = STRING_NOTFOUND != rForm.SearchAscii( "MMM" );
507 // MMMM -> full month
508 sal_Bool bFullMonth = STRING_NOTFOUND != rForm.SearchAscii( "MMMM" );
509 // jj, JJ -> 2-col-year
510 // jjjj, JJJJ -> 4-col-year
511 sal_Bool bFullYear = STRING_NOTFOUND != rForm.SearchAscii( "jjj" ) ||
512 STRING_NOTFOUND != rForm.SearchAscii( "JJJ" ) ||
513 STRING_NOTFOUND != rForm.SearchAscii( "yyy" ) ||
514 STRING_NOTFOUND != rForm.SearchAscii( "YYY" );
516 sal_uInt16 i = ( bLitMonth & 1 )
517 | ( ( bFullYear & 1 ) << 1 )
518 | ( ( bFullMonth & 1 ) << 2 )
519 | ( ( bDayOfWeek & 1 ) << 3 )
520 | ( ( bLongDayOfWeek & 1 ) << 4 );
521 if( pDate )
523 if( !bHasDay && !bFullMonth )
524 *pDate = DFF_MY;
525 else
526 *pDate = aDateA[i];
529 else
531 eDT = (WWDateTime)( eDT & ~(sal_uInt16)WW_DATE );
533 return eDT;
537 extern void sw3io_ConvertFromOldField( SwDoc& rDoc, sal_uInt16& rWhich,
538 sal_uInt16& rSubType, sal_uLong &rFmt,
539 sal_uInt16 nVersion );
541 void Ww1Fields::Out(Ww1Shell& rOut, Ww1Manager& rMan, sal_uInt16 nDepth)
543 String sType; // der typ als string
544 String sFormel; // die formel
545 String sFormat;
546 String sDTFormat; // Datum / Zeit-Format
547 W1_FLD* pData = GetData(); // die an den plc gebunden daten
548 OSL_ENSURE(pData->chGet()==19, "Ww1Fields"); // sollte beginn sein
550 sal_Unicode c;
551 rMan.Fill( c );
552 OSL_ENSURE(c==19, "Ww1Fields"); // sollte auch beginn sein
553 if (pData->chGet()==19 && c == 19)
555 String aStr;
556 c = rMan.Fill( aStr, GetLength() );
557 OSL_ENSURE(Ww1PlainText::IsChar(c), "Ww1Fields");
558 xub_StrLen pos = aStr.Search(' ');
559 // get type out of text
560 sType = aStr.Copy( 0, pos );
561 aStr.Erase( 0, pos );
562 if ( pos != STRING_NOTFOUND )
563 aStr.Erase(0, 1);
564 sFormel += aStr;
565 sal_uInt8 rbType = pData->fltGet();
566 do {
567 // solange den formelteil einlesen, bis das feld entweder
568 // zuende ist oder der ergebnisteil beginnt. dabei koennen
569 // natuerlich neue felder beginnen (word unterstuetzt felder,
570 // die wiederum felder beinhalten).
571 ++(*this);
572 pData = GetData();
573 if (pData->chGet()==19) // nested field
575 Out(rOut, rMan, nDepth+1);
576 rMan.Fill(c);
577 OSL_ENSURE(c==21, "Ww1PlainText");
578 sFormel.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "Ww" ));
579 sFormel += OUString::number( nPlcIndex );
580 c = rMan.Fill(aStr, GetLength());
581 OSL_ENSURE(Ww1PlainText::IsChar(c), "Ww1PlainText");
582 sFormel += aStr;
585 while (pData->chGet()==19);
587 // get format out of text
588 pos = sFormel.SearchAscii( "\\*" );
589 sFormat = sFormel.Copy( pos );
590 sFormel.Erase( pos );
592 pos = sFormel.SearchAscii( "\\@" );
593 sDTFormat = sFormel.Copy( pos );
594 sFormel.Erase( pos );
596 // der formelteil ist zuende, kommt ein ergebnisteil?
597 if( pData->chGet() == 20 )
599 rMan.Fill( c );
600 OSL_ENSURE(c==20, "Ww1PlainText");
601 c = rMan.Fill(sErgebnis, GetLength());
602 if (!Ww1PlainText::IsChar(c))
603 sErgebnis += c; //~ mdt: sonderzeichenbenhandlung
604 ++(*this);
605 pData = GetData();
607 OSL_ENSURE(pData->chGet()==21, "Ww1PlainText");
608 bool bKnown = true;
609 OSL_ENSURE(pField==0, "Ww1PlainText");
610 if (pField != 0)
612 rOut << *pField;
613 delete pField;
614 pField = 0;
616 // naja, aber info enthaelt alle moeglichkeiten, die auch direkt da sind
617 oncemore:
618 switch (rbType)
620 case 3: // bookmark reference
621 rOut.ConvertUStr( sFormel );
622 pField = new SwGetRefField( (SwGetRefFieldType*)
623 rOut.GetSysFldType( RES_GETREFFLD ),
624 sFormel,
625 REF_BOOKMARK,
627 REF_CONTENT );
629 break;
630 case 6: // set command
632 pos = aStr.Search(' ');
633 String aName( aStr.Copy( 0, pos ));
634 aStr.Erase(0, pos );
635 aStr.Erase(0, 1);
636 if( !aName.Len() )
637 break;
638 rOut.ConvertUStr( aName );
639 SwFieldType* pFT = rOut.GetDoc().InsertFldType(
640 SwSetExpFieldType( &rOut.GetDoc(), aName, nsSwGetSetExpType::GSE_STRING ) );
641 pField = new SwSetExpField((SwSetExpFieldType*)pFT, aStr);
642 ((SwSetExpField*)pField)->SetSubType( nsSwExtendedSubType::SUB_INVISIBLE );
643 // Invisible macht in 378 AErger, soll aber demnaechst gehen
645 // das Ignorieren des Bookmarks ist nicht implementiert
647 break;
648 case 14: // info var
650 pos = aStr.Search(' ');
651 String aSubType( aStr.Copy( 0, pos ));
652 aStr.Erase(0, pos );
653 aStr.Erase(0, 1);
654 rOut.ConvertUStr( aSubType );
657 // ganz grosze schiete: der typ 'info' kann einem der
658 // typen 15..31 entsprechen. er enthaelt als formel
659 // das eingentliche feld der doc-info.
660 // kein ';' benutzen mit folgendem macro:
661 #define IS(sd, se, t) \
662 if (aSubType.EqualsAscii( sd ) || aSubType.EqualsAscii( se)) \
663 rbType = t; \
664 else
666 // deutsche bez. englische bez. typ-code
667 IS("titel", "title", 15)
668 IS("thema", "subject", 16)
669 IS("autor", "author", 17)
670 IS("stichw?rter", "keywords", 18) //~ mdt: umlaut
671 IS("kommentar", "comment", 19)
672 IS("gespeichertvon", "lastrevisedby", 20)
673 IS("ertelldat", "creationdate", 21)
674 IS("speicherdat", "revisiondate", 22)
675 IS("druckdat", "printdate", 23)
676 IS("version", "revisionnumber", 24)
677 IS("zeit", "edittime", 25)
678 IS("anzseit", "numberofpages", 26)
679 IS("anzw?rter", "numberofwords", 27) //~ mdt: umlaut
680 IS("anzzeichen", "numberofchars", 28)
681 IS("dateiname", "filename", 29)
682 IS("vorlage", "templatename", 30)
683 bKnown = false;
684 #undef IS
685 if (rbType != 14)
686 goto oncemore;
688 break;
689 case 15: // title
690 pField = new SwDocInfoField((SwDocInfoFieldType*)
691 rOut.GetSysFldType(RES_DOCINFOFLD), DI_TITEL, String(), 0);
692 break;
693 case 16: // subject
694 pField = new SwDocInfoField((SwDocInfoFieldType*)
695 rOut.GetSysFldType(RES_DOCINFOFLD), DI_THEMA, String(), 0);
696 break;
697 case 17: // author
698 pField = new SwAuthorField((SwAuthorFieldType*)
699 rOut.GetSysFldType(RES_AUTHORFLD), AF_NAME );
700 break;
701 case 18: // keywords
702 pField = new SwDocInfoField((SwDocInfoFieldType*)
703 rOut.GetSysFldType(RES_DOCINFOFLD), DI_KEYS, String(), 0);
704 break;
705 case 19: // comments
706 pField = new SwDocInfoField((SwDocInfoFieldType*)
707 rOut.GetSysFldType(RES_DOCINFOFLD), DI_COMMENT, String(), 0);
708 break;
709 case 20: // last revised by
710 pField = new SwDocInfoField((SwDocInfoFieldType*)
711 rOut.GetSysFldType(RES_DOCINFOFLD), DI_CHANGE|DI_SUB_AUTHOR, String());
712 break;
713 case 21: // creation date
714 case 22: // revision date
715 case 23: // print date
716 case 25:{// edit time
717 sal_uInt16 nSub;
718 sal_uInt16 nReg = 0; // RegInfoFormat, DefaultFormat fuer DocInfoFelder
720 switch( rbType )
722 default:
723 case 21: nSub = DI_CREATE; nReg = DI_SUB_DATE; break;
724 case 23: nSub = DI_PRINT; nReg = DI_SUB_DATE; break;
725 case 22: nSub = DI_CHANGE; nReg = DI_SUB_DATE; break;
726 case 25: nSub = DI_CHANGE; nReg = DI_SUB_TIME; break;
728 switch( GetTimeDatePara( sDTFormat ) )
730 case WW_DATE: nReg = DI_SUB_DATE; break;
731 case WW_TIME: nReg = DI_SUB_TIME; break;
732 case WW_BOTH: nReg = DI_SUB_DATE; break;
733 default:
734 break;
735 // WW_DONTKNOW -> Default bereits gesetzt
737 pField = new SwDocInfoField((SwDocInfoFieldType*)
738 rOut.GetSysFldType(RES_DOCINFOFLD), nSub | nReg, String());
740 break;
741 case 24: // revision number
742 pField = new SwDocInfoField((SwDocInfoFieldType*)
743 rOut.GetSysFldType(RES_DOCINFOFLD), DI_DOCNO, String(), 0);
744 break;
745 case 26: // number of pages
746 pField = new SwDocStatField((SwDocStatFieldType*)
747 rOut.GetSysFldType(RES_DOCSTATFLD), DS_PAGE, SVX_NUM_ARABIC);
748 break;
749 case 27: // number of words
750 pField = new SwDocStatField((SwDocStatFieldType*)
751 rOut.GetSysFldType(RES_DOCSTATFLD), DS_WORD, SVX_NUM_ARABIC);
752 break;
753 case 28: // number of chars
754 pField = new SwDocStatField((SwDocStatFieldType*)
755 rOut.GetSysFldType(RES_DOCSTATFLD), DS_CHAR, SVX_NUM_ARABIC);
756 break;
757 case 29: // file name
758 pField = new SwFileNameField((SwFileNameFieldType*)
759 rOut.GetSysFldType(RES_FILENAMEFLD));
760 break;
761 case 30: // doc template name
762 pField = new SwTemplNameField((SwTemplNameFieldType*)
763 rOut.GetSysFldType(RES_TEMPLNAMEFLD), FF_NAME);
764 break;
765 case 31:
766 case 32:{
767 SwDateFormat aDate = DF_SSYS;
768 SwTimeFormat aTime = TF_SYSTEM;
770 WWDateTime eDT = GetTimeDatePara(sDTFormat, &aTime, &aDate);
771 if( eDT == WW_DONTKNOW ) // kein D/T-Formatstring
772 eDT = ( rbType == 32 ) ? WW_TIME : WW_DATE; // benutze ID
774 if( eDT & WW_DATE )
776 sal_uInt16 nWhich = RES_DATEFLD;
777 sal_uInt16 nSubType = DATEFLD;
778 sal_uLong nFormat = aDate;
779 sw3io_ConvertFromOldField( rOut.GetDoc(),
780 nWhich, nSubType, nFormat, 0x0110 );
781 pField = new SwDateTimeField((SwDateTimeFieldType*)
782 rOut.GetSysFldType(RES_DATETIMEFLD), DATEFLD, nFormat);
784 if( eDT == WW_BOTH )
785 rOut << * pField << ' ';
786 // Mogel: direkt einfuegen und Space dahinter
788 if( eDT & WW_TIME )
790 sal_uInt16 nWhich = RES_TIMEFLD;
791 sal_uInt16 nSubType = TIMEFLD;
792 sal_uLong nFormat = aTime;
793 sw3io_ConvertFromOldField( rOut.GetDoc(),
794 nWhich, nSubType, nFormat, 0x0110 );
795 pField = new SwDateTimeField((SwDateTimeFieldType*)
796 rOut.GetSysFldType(RES_DATETIMEFLD), TIMEFLD, nFormat);
800 break;
801 case 33: // current page
802 pField = new SwPageNumberField((SwPageNumberFieldType*)
803 rOut.GetSysFldType(RES_PAGENUMBERFLD), PG_RANDOM, SVX_NUM_ARABIC);
804 break;
805 case 34: // evaluation exp
807 if (nDepth == 0)
809 SwGetExpFieldType* pFieldType =
810 (SwGetExpFieldType*)rOut.GetSysFldType(RES_GETEXPFLD);
811 OSL_ENSURE(pFieldType!=0, "Ww1Fields");
812 if (pFieldType != 0)
813 pField = new SwGetExpField(pFieldType, sFormel,
814 nsSwGetSetExpType::GSE_STRING, VVF_SYS);
816 else // rekursion:
818 OUString aName("Ww");
819 aName += OUString::number( nPlcIndex );
820 SwFieldType* pFT = rOut.GetDoc().GetFldType( RES_SETEXPFLD, aName, false);
821 if (pFT == 0)
823 SwSetExpFieldType aS(&rOut.GetDoc(), aName, nsSwGetSetExpType::GSE_FORMULA);
824 pFT = rOut.GetDoc().InsertFldType(aS);
826 SwSetExpField aFld((SwSetExpFieldType*)pFT, sFormel);
827 aFld.SetSubType(nsSwExtendedSubType::SUB_INVISIBLE);
828 rOut << aFld;
831 break;
832 case 36: // print command, Einfuegendatei
834 pos = aStr.Search(' ');
835 String aFName( aStr.Copy( 0, pos ));
836 aStr.Erase(0, pos );
837 aStr.Erase(0, 1);
838 if( !aFName.Len() )
839 break;
840 aFName.SearchAndReplaceAscii( "\\\\", OUString('\\') );
842 aFName = URIHelper::SmartRel2Abs(
843 INetURLObject(rOut.GetBaseURL()), aFName );
845 SwSectionData * pSection = new SwSectionData( FILE_LINK_SECTION,
846 rOut.GetDoc().GetUniqueSectionName( &aStr ) );
847 pSection->SetLinkFileName( aFName );
848 pSection->SetProtectFlag( true );
849 rOut << SwFltSection( pSection );
850 rOut.EndItem( RES_FLTR_SECTION );
851 rOut.NextParagraph();
853 case 37: // page ref
854 pField = new SwGetRefField(
855 (SwGetRefFieldType*)rOut.GetSysFldType(RES_GETREFFLD),
856 sFormel, 0, 0, REF_PAGE);
857 break;
858 case 38: // ask command
860 pos = aStr.Search(' ');
861 String aName( aStr.Copy( 0, pos ));
862 aStr.Erase(0, pos );
863 aStr.Erase(0, 1);
864 if( !aName.Len() )
865 break;
867 SwFieldType* pFT = rOut.GetDoc().InsertFldType(
868 SwSetExpFieldType( &rOut.GetDoc(), aName, nsSwGetSetExpType::GSE_STRING ) );
869 pField = new SwSetExpField((SwSetExpFieldType*)pFT, aStr );
870 ((SwSetExpField*)pField)->SetInputFlag( sal_True );
871 ((SwSetExpField*)pField)->SetSubType(nsSwExtendedSubType::SUB_INVISIBLE);
873 case 39: // fillin command
874 pField = new SwInputField(
875 (SwInputFieldType*)rOut.GetSysFldType( RES_INPUTFLD ),
876 aEmptyStr, sFormel,
877 INP_TXT, 0 ); // sichtbar ( geht z.Zt. nicht anders )
878 break;
879 case 51: // macro button
881 pos = aStr.Search(' ');
882 String aName( aStr.Copy( 0, pos ));
883 aStr.Erase(0, pos );
884 aStr.Erase(0, 1);
885 if( !aName.Len() || !aStr.Len() )
886 break;
887 aName.InsertAscii( "StarOffice.Standard.Modul1.", 0 );
889 pField = new SwMacroField( (SwMacroFieldType*)
890 rOut.GetSysFldType( RES_MACROFLD ),
891 aName, aStr );
893 break;
894 case 55: // read tiff / or better: import anything
896 const sal_Unicode* pFormel = sFormel.GetBuffer();
897 const sal_Unicode* pDot = 0;
898 String sName;
899 while (*pFormel != '\0' && *pFormel != ' ')
901 // ab hier koennte eine extension kommen
902 if (*pFormel == '.')
903 pDot = pFormel;
904 else
905 // aha: wir waren bislang noch in dirs
906 if (*pFormel == '\\')
908 pDot = 0;
909 if (pFormel[1] == '\\')
910 pFormel++;
912 if (*pFormel != '\0')
913 sName += *pFormel++;
915 if( pDot )
917 String sExt;
918 while( *pDot != '\0' && *pDot != ' ')
919 sExt += *pDot++;
921 if( sExt.EqualsIgnoreCaseAscii( ".tiff" )
922 || sExt.EqualsIgnoreCaseAscii( ".bmp" )
923 || sExt.EqualsIgnoreCaseAscii( ".gif" )
924 || sExt.EqualsIgnoreCaseAscii( ".pcx" )
925 || sExt.EqualsIgnoreCaseAscii( ".pic" ))
926 rOut.AddGraphic( sName );
927 else
928 bKnown = false;
930 else
931 bKnown = false;
933 break;
934 default: // unknown
935 OSL_ENSURE(false, "Ww1PlainText");
936 // unsupported:
937 case 1: // unknown
938 case 2: // possible bookmark
939 case 4: // index entry
940 // wwpar5: 1351/1454
941 case 5: // footnote ref
942 case 7: // if command
943 case 8: // create index
944 // wwpar5: 1351/1454
945 case 9: // table of contents entry
946 // wwpar5: 1351/1454
947 case 10: // style ref
948 case 11: // doc ref
949 case 12: // seq ref
950 case 13: // create table of contents
951 // wwpar5: 1351/1454
952 case 35: // literal text
953 // print merge:
954 case 40: // data command
955 case 41: // next command
956 case 42: // nextif command
957 case 43: // skipif command
958 case 44: // number of record
960 case 45: // dde ref
961 case 46: // dde auto ref
962 case 47: // glossary entry
963 case 48: // print char
964 case 49: // formula def
965 case 50: // goto button
966 case 52: // auto number outline
967 case 53: // auto number legal
968 case 54: // auto number arabic
969 bKnown = false;
970 break;
972 if( bKnown || sErgebnis.EqualsAscii( "\270" ))
973 this->sErgebnis.Erase();
974 else
975 this->sErgebnis = sErgebnis;
977 else // oops: we are terribly wrong: skip this
978 ++(*this);
981 sal_uLong Ww1Fields::GetLength()
983 // berechnet die laenge eines feldteiles. nicht mitgerechnet werden
984 // die terminierenden zeichen im text (19, 20, 21) die beginn, trenner
985 // und ende bedeuten.
986 sal_uLong ulBeg = Where();
987 sal_uLong ulEnd = Where(nPlcIndex+1);
988 OSL_ENSURE(ulBeg<ulEnd, "Ww1Fields");
989 return (ulEnd - ulBeg) - 1;
992 /////////////////////////////////////////////////////////////////// Sep
993 void Ww1Sep::Start(Ww1Shell& rOut, Ww1Manager& rMan)
995 if (rMan.Where() >= Where())
997 rOut.NextSection();
998 SwFrmFmt &rFmt = rOut.GetPageDesc().GetMaster();
999 W1_DOP& rDOP = rMan.GetDop().GetDOP();
1000 rOut.GetPageDesc().SetLandscape(rDOP.fWideGet());
1001 SwFmtFrmSize aSz(rFmt.GetFrmSize());
1002 aSz.SetWidth(rDOP.xaPageGet());
1003 aSz.SetHeight(rDOP.yaPageGet());
1004 rFmt.SetFmtAttr(aSz);
1005 SvxLRSpaceItem aLR(rDOP.dxaLeftGet()+rDOP.dxaGutterGet(),
1006 rDOP.dxaRightGet(), 0, 0, RES_LR_SPACE);
1007 rFmt.SetFmtAttr(aLR);
1008 SvxULSpaceItem aUL(rDOP.dyaTopGet(), rDOP.dyaBottomGet(), RES_UL_SPACE);
1009 rFmt.SetFmtAttr(aUL);
1010 // sobald wir mit dem lesen der zeichen soweit sind, wo sep's
1011 // momentanes attribut beginnt, wird dieses attribut eingefuegt.
1012 // diese methode ist bei den meisten start/stop methoden der
1013 // memberklassen des managers identisch.
1014 sal_uInt8* pByte = GetData();
1015 Ww1SprmSep aSprm(rFib, SVBT32ToUInt32(pByte + 2));
1016 aSprm.Start(rOut, rMan);
1017 aSprm.Stop(rOut, rMan);
1018 ++(*this);
1019 aHdd.Start(rOut, rMan);
1023 /////////////////////////////////////////////////////////////////// Pap
1024 void Ww1Pap::Start(Ww1Shell& rOut, Ww1Manager& rMan)
1026 if (rMan.Where() >= Where())
1028 sal_uInt8* pByte;
1029 sal_uInt16 cb;
1030 // bereitstellen der zu startenden attribute
1031 if (FillStart(pByte, cb))
1033 Ww1SprmPapx aSprm(pByte, cb);
1034 // und ausgeben:
1035 aSprm.Start(rOut, rMan);
1037 ++(*this);
1041 void Ww1Pap::Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode&)
1043 if (rMan.Where() >= Where() || rMan.IsStopAll())
1045 sal_uInt8* pByte;
1046 sal_uInt16 cb;
1047 if (FillStop(pByte, cb)){
1048 Ww1SprmPapx aSprm(pByte, cb);
1049 aSprm.Stop(rOut, rMan);
1050 }else{
1051 OSL_ENSURE( !nPlcIndex || rMan.IsStopAll(), "Pap-Attribut-Stop verloren" );
1056 //////////////////////////////////////////////////////////////// W1_CHP
1058 // momentan laesst sich die ausgabe von W1CHPxen nicht nur per define
1059 // loesen....
1061 void W1_CHP::Out(Ww1Shell& rOut, Ww1Manager& rMan)
1063 if (fBoldGet())
1064 rOut << SvxWeightItem(
1065 rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT);
1066 if (fItalicGet())
1067 rOut << SvxPostureItem(
1068 rOut.GetPostureItalic()?ITALIC_NONE:ITALIC_NORMAL, RES_CHRATR_POSTURE);
1069 if (fStrikeGet())
1070 rOut << SvxCrossedOutItem(
1071 rOut.GetCrossedOut()?STRIKEOUT_NONE:STRIKEOUT_SINGLE, RES_CHRATR_CROSSEDOUT);
1072 if (fOutlineGet())
1073 rOut << SvxContourItem(!rOut.GetContour(), RES_CHRATR_CONTOUR);
1074 if (fSmallCapsGet())
1075 rOut << SvxCaseMapItem(
1076 rOut.GetCaseKapitaelchen()?SVX_CASEMAP_NOT_MAPPED:SVX_CASEMAP_KAPITAELCHEN, RES_CHRATR_CASEMAP);
1077 if (fCapsGet())
1078 rOut << SvxCaseMapItem(
1079 rOut.GetCaseVersalien()?SVX_CASEMAP_NOT_MAPPED:SVX_CASEMAP_VERSALIEN, RES_CHRATR_CASEMAP);
1080 if (fsHpsGet())
1081 rOut << SvxFontHeightItem(hpsGet() * 10, 100, RES_CHRATR_FONTSIZE);
1082 if (fsKulGet())
1083 switch (kulGet()) {
1084 case 0: {
1085 rOut << SvxUnderlineItem(UNDERLINE_NONE, RES_CHRATR_UNDERLINE) <<
1086 SvxWordLineModeItem(sal_False, RES_CHRATR_WORDLINEMODE);
1087 } break;
1088 default: OSL_ENSURE(false, "Chpx");
1089 case 1: {
1090 rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE);
1091 } break;
1092 case 2: {
1093 rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE) <<
1094 SvxWordLineModeItem(sal_True, RES_CHRATR_WORDLINEMODE);
1095 } break;
1096 case 3: {
1097 rOut << SvxUnderlineItem(UNDERLINE_DOUBLE, RES_CHRATR_UNDERLINE);
1098 } break;
1099 case 4: {
1100 rOut << SvxUnderlineItem(UNDERLINE_DOTTED, RES_CHRATR_UNDERLINE);
1101 } break;
1104 if (fsIcoGet())
1105 switch(icoGet()) {
1106 default: OSL_ENSURE(false, "Chpx");
1107 case 0: { rOut.EndItem(RES_CHRATR_COLOR); } break;
1108 case 1: { rOut << SvxColorItem(Color(COL_BLACK), RES_CHRATR_COLOR); } break;
1109 case 2: { rOut << SvxColorItem(Color(COL_LIGHTBLUE), RES_CHRATR_COLOR); } break;
1110 case 3: { rOut << SvxColorItem(Color(COL_LIGHTCYAN), RES_CHRATR_COLOR); } break;
1111 case 4: { rOut << SvxColorItem(Color(COL_LIGHTGREEN), RES_CHRATR_COLOR); } break;
1112 case 5: { rOut << SvxColorItem(Color(COL_LIGHTMAGENTA), RES_CHRATR_COLOR); } break;
1113 case 6: { rOut << SvxColorItem(Color(COL_LIGHTRED), RES_CHRATR_COLOR); } break;
1114 case 7: { rOut << SvxColorItem(Color(COL_YELLOW), RES_CHRATR_COLOR); } break;
1115 case 8: { rOut << SvxColorItem(Color(COL_WHITE), RES_CHRATR_COLOR); } break;
1117 if (fsSpaceGet()) {
1118 short sQps = qpsSpaceGet();
1119 if (sQps > 56)
1120 sQps = sQps - 64;
1121 rOut << SvxKerningItem(sQps, RES_CHRATR_KERNING);
1123 if (fsPosGet()) {
1124 if (hpsPosGet() == 0)
1125 rOut << SvxEscapementItem(SVX_ESCAPEMENT_OFF, 100, RES_CHRATR_ESCAPEMENT);
1126 else {
1127 short sHps = hpsPosGet();
1128 if (sHps > 128)
1129 sHps = sHps - 256;
1130 sHps *= 100;
1131 sHps /= 24;
1132 rOut << SvxEscapementItem(sHps, 100, RES_CHRATR_ESCAPEMENT);
1135 if (fsFtcGet()) {
1136 SvxFontItem aFont(rMan.GetFont(ftcGet()));
1137 rOut << aFont;
1141 /////////////////////////////////////////////////////////////////// Chp
1142 void Ww1Chp::Start(Ww1Shell& rOut, Ww1Manager& rMan)
1144 if (rMan.Where() >= Where())
1146 W1_CHP aChpx;
1147 if (FillStart(aChpx))
1149 aChpx.Out(rOut, rMan);
1150 if (aChpx.fcPicGet())
1152 Ww1Picture aPic(rMan.GetFib().GetStream(),
1153 aChpx.fcPicGet());
1154 if (!aPic.GetError())
1155 aPic.Out(rOut, rMan);
1158 ++(*this);
1162 void Ww1Chp::Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode&)
1164 if (rMan.Where() >= Where())
1166 W1_CHP aChpx;
1167 if (FillStop(aChpx))
1169 // zuerst alle toggle-flags
1170 if (aChpx.fBoldGet())
1171 rOut.EndItem(RES_CHRATR_WEIGHT);
1172 if (aChpx.fItalicGet())
1173 rOut.EndItem(RES_CHRATR_POSTURE);
1174 if (aChpx.fStrikeGet())
1175 rOut.EndItem(RES_CHRATR_CROSSEDOUT);
1176 if (aChpx.fOutlineGet())
1177 rOut.EndItem(RES_CHRATR_CONTOUR);
1178 if (aChpx.fSmallCapsGet() || aChpx.fCapsGet())
1179 rOut.EndItem(RES_CHRATR_CASEMAP);
1180 // dann alle zahl-werte, diese haben flags, wenn sie gesetzt
1181 // sind..................
1182 if (aChpx.fsHpsGet())
1183 rOut.EndItem(RES_CHRATR_FONTSIZE);
1184 if (aChpx.fsKulGet())
1185 rOut.EndItem(RES_CHRATR_UNDERLINE)
1186 .EndItem(RES_CHRATR_WORDLINEMODE);
1187 if (aChpx.fsIcoGet())
1188 rOut.EndItem(RES_CHRATR_COLOR);
1189 if (aChpx.fsSpaceGet())
1190 rOut.EndItem(RES_CHRATR_KERNING);
1191 if (aChpx.fsPosGet())
1192 rOut.EndItem(RES_CHRATR_ESCAPEMENT);
1193 if (aChpx.fsFtcGet())
1194 rOut.EndItem(RES_CHRATR_FONT);
1195 }else{
1196 OSL_ENSURE( !nPlcIndex, "Chp-Attribut-Stop verloren" );
1201 ///////////////////////////////////////////////////////////////// Style
1202 void Ww1Style::Out(Ww1Shell& rOut, Ww1Manager& rMan)
1204 // Zuerst Basis, damit Attribute des Basis-Styles erkannt werden
1205 // first: Base................................................
1206 if(pParent->GetStyle(stcBase).IsUsed() ) // Basis gueltig ?
1207 rOut.BaseStyle(stcBase);
1209 // next of all: CHP...............................................
1210 aChpx.Out(rOut, rMan);
1211 // Last: PAP.......................................................
1212 if (pPapx)
1213 pPapx->Start(rOut, rMan);
1216 ////////////////////////////////////////////////////////// Ww1PlainText
1218 // die Out() methoden von plaintext fuer den filter geben eine anzahl
1219 // zeichen aus auf die shell, einen string oder einen char, wieviel
1220 // zeichen ausgegeben werden, bestimmt ulEnd, das das ende bestimmt,
1221 // bis zudem ausgegeben wird. ausserdem beenden die methoden die
1222 // ausgabe bei kontrollzeichen.
1223 // diese sind definiert durch MinChar. alle zeichen mit wert darunter
1224 // gelten als kontroll- zeichen. dafuer gibts die methode IsChar, die
1225 // zurueckgibt, ob es sich um ein standard zeichen handelt. kommt ein
1226 // solches zeichen, wird dieses zeichen zurueckgegeben und die methode
1227 // beendet, auch wenn ulEnd noch nicht erreicht wurde. bei nutzung
1228 // also beachten, dasz wenn !IsChar(Out(...)) gilt, ulEnd unter
1229 // umstaenden nicht erreicht wurde. dann wurde das kontrollzeichen
1230 // zwar (weg-)gelesen, jedoch noch nicht ausgegeben.
1232 sal_Unicode Ww1PlainText::Out( Ww1Shell& rOut, sal_uLong& ulEnd )
1234 // gibt die zeichen bis ulEnd aus, es sei den es kommen sonderzeichen
1235 // die eine bedeutung haben wie absatzende oder seitenumbruch.
1236 if (ulEnd > Count())
1237 ulEnd = Count();
1238 while (ulSeek < ulEnd)
1240 sal_Unicode c = (*this)[ulSeek];
1241 ++(*this);
1242 if (Ww1PlainText::IsChar(c))
1243 rOut << c;
1244 else
1245 return c;
1247 return Ww1PlainText::MinChar;
1250 sal_Unicode Ww1PlainText::Out( String& rStr, sal_uLong ulEnd )
1252 // wie Out(Shell..., jedoch ausgabe auf einen string
1253 rStr.Erase();
1254 if (ulEnd > Count())
1255 ulEnd = Count();
1256 while (ulSeek < ulEnd)
1258 sal_Unicode c = (*this)[ulSeek];
1259 ++(*this);
1260 if( Ww1PlainText::IsChar(c) )
1261 rStr += c;
1262 else
1263 return c;
1265 return Ww1PlainText::MinChar;
1269 // hier eruebrigt sich ulEnd...oder?
1271 sal_Unicode Ww1PlainText::Out( sal_Unicode& rRead )
1273 rRead = (*this)[ulSeek];
1274 ++(*this);
1275 return rRead;
1278 /////////////////////////////////////////////////////////// Ww1SprmPapx
1280 void Ww1SprmPapx::Start(Ww1Shell& rOut, Ww1Manager& rMan)
1282 if( !rMan.IsInStyle() ){ // Innerhalb Style gehts ueber die
1283 // normalen Attribute
1284 if (!rOut.IsInFly()
1285 && !rOut.IsInTable() // Nicht innerhalb Tabelle!
1286 && ( rMan.HasPPc() || rMan.HasPDxaAbs())){ // Fly-Start
1287 rOut.BeginFly(); // eAnchor );
1289 if (!rOut.IsInTable() && rMan.HasInTable())
1291 rOut.BeginTable();
1293 rOut.SetStyle(aPapx.stcGet());
1295 Ww1Sprm::Start(rOut, rMan);
1298 void Ww1SprmPapx::Stop(Ww1Shell& rOut, Ww1Manager& rMan)
1300 Ww1Sprm::Stop(rOut, rMan);
1302 if( !rMan.IsInStyle() ) // Innerhalb Style gehts ueber die
1303 { // normalen Attribute
1304 if (rOut.IsInTable() &&( rMan.IsStopAll() || !rMan.HasInTable()))
1305 rOut.EndTable();
1307 if( rOut.IsInFly() &&
1308 ( rMan.IsStopAll()
1309 || ( !rMan.HasPPc() && !rMan.HasPDxaAbs() // Fly-Ende
1310 && !rOut.IsInTable()))) // Nicht innerhalb Tabelle!
1311 rOut.EndFly();
1315 ///////////////////////////////////////////////////////////////// Fonts
1316 SvxFontItem Ww1Fonts::GetFont(sal_uInt16 nFCode)
1318 // erzeugen eine fonts im sw-sinne aus den word-strukturen
1319 FontFamily eFamily = FAMILY_DONTKNOW;
1320 String aName;
1321 FontPitch ePitch = PITCH_DONTKNOW;
1322 rtl_TextEncoding eCharSet = RTL_TEXTENCODING_DONTKNOW;
1323 switch (nFCode)
1325 // In the Winword 1.x format, the names of the first three fonts were
1326 // omitted from the table and assumed to be "Tms Rmn" (for ftc = 0),
1327 // "Symbol", and "Helv"
1328 case 0:
1329 eFamily = FAMILY_ROMAN;
1330 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Tms Rmn" ));
1331 ePitch = PITCH_VARIABLE;
1332 eCharSet = RTL_TEXTENCODING_MS_1252;
1333 break;
1334 case 1:
1335 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Symbol" ));
1336 ePitch = PITCH_VARIABLE;
1337 eCharSet = RTL_TEXTENCODING_SYMBOL;
1338 break;
1339 case 2:
1340 eFamily = FAMILY_SWISS;
1341 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helv" ));
1342 ePitch = PITCH_VARIABLE;
1343 eCharSet = RTL_TEXTENCODING_MS_1252;
1344 break;
1345 default:
1347 W1_FFN* pF = GetFFN(nFCode - 3);
1348 if (pF != 0)
1350 // Fontname .........................................
1351 aName = String( (sal_Char*)pF->szFfnGet(),
1352 RTL_TEXTENCODING_MS_1252 );
1353 // Pitch .............................................
1354 static FontPitch ePitchA[] =
1356 PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, PITCH_DONTKNOW
1358 ePitch = ePitchA[pF->prgGet()];
1359 // CharSet ...........................................
1360 eCharSet = RTL_TEXTENCODING_MS_1252;
1361 if (aName.EqualsIgnoreCaseAscii("Symbol")
1362 || aName.EqualsIgnoreCaseAscii("Symbol Set")
1363 || aName.EqualsIgnoreCaseAscii("Wingdings")
1364 || aName.EqualsIgnoreCaseAscii("ITC Zapf Dingbats") )
1365 eCharSet = RTL_TEXTENCODING_SYMBOL;
1366 // FontFamily ........................................
1367 sal_uInt16 b = pF->ffGet();
1368 static FontFamily eFamilyA[] =
1370 FAMILY_DONTKNOW, FAMILY_ROMAN, FAMILY_SWISS, FAMILY_MODERN,
1371 FAMILY_SCRIPT, FAMILY_DECORATIVE
1373 if (b < (sizeof(eFamilyA)/sizeof(eFamilyA[0])))
1374 eFamily = eFamilyA[b];
1376 else
1378 OSL_ENSURE(false, "WW1Fonts::GetFont: Nicht existenter Font !");
1379 eFamily = FAMILY_SWISS;
1380 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helv" ));
1381 ePitch = PITCH_VARIABLE;
1382 eCharSet = RTL_TEXTENCODING_MS_1252;
1385 break;
1387 // Extrawurst Hypo
1388 if ( SwFltGetFlag( nFieldFlags, SwFltControlStack::HYPO )
1389 && ( aName.EqualsIgnoreCaseAscii("Helv")
1390 || aName.EqualsIgnoreCaseAscii("Helvetica") ) )
1392 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica Neue" ));
1393 if (eFamily==FAMILY_DONTKNOW)
1394 eFamily = FAMILY_SWISS;
1396 else
1398 // VCL matcht die Fonts selber
1399 // allerdings passiert bei Helv, Tms Rmn und System Monospaced
1400 // Scheisse, so dass diese ersetzt werden muessen.
1401 // Nach TH sollen diese durch feste Werte ersetzt werden,
1402 // also nicht ueber System::GetStandardFont, damit keine
1403 // Namenslisten auftauchen ( Dieses koennte den User verwirren )
1404 if( aName.EqualsIgnoreCaseAscii("Helv"))
1406 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Helvetica" ));
1407 if (eFamily==FAMILY_DONTKNOW)
1408 eFamily = FAMILY_SWISS;
1410 else if (aName.EqualsIgnoreCaseAscii("Tms Rmn"))
1412 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Times New Roman" ));
1413 if (eFamily==FAMILY_DONTKNOW)
1414 eFamily = FAMILY_ROMAN;
1416 else if (aName.EqualsIgnoreCaseAscii("System Monospaced") )
1418 aName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Courier" ));
1419 ePitch = PITCH_FIXED;
1422 // nun koennen wir den font basteln: .........................
1423 return SvxFontItem(eFamily, aName, aEmptyStr, ePitch, eCharSet, RES_CHRATR_FONT);
1426 /////////////////////////////////////////////////////////////////// Dop
1427 void Ww1Dop::Out(Ww1Shell& rOut)
1429 //~ mdt: fehlt
1430 long nDefTabSiz = aDop.dxaTabGet();
1431 if (nDefTabSiz < 56)
1432 nDefTabSiz = 709;
1434 // wir wollen genau einen DefaultTab
1435 SvxTabStopItem aNewTab(1, sal_uInt16(nDefTabSiz), SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP);
1436 ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
1437 rOut.GetDoc().GetAttrPool().SetPoolDefaultItem( aNewTab); //~ mdt: besser (GetDoc)
1439 SwFrmFmt &rFmt = rOut.GetPageDesc().GetMaster();
1440 W1_DOP& rDOP = GetDOP();
1441 rOut.GetPageDesc().SetLandscape(rDOP.fWideGet());
1442 SwFmtFrmSize aSz(rFmt.GetFrmSize());
1443 aSz.SetWidth(rDOP.xaPageGet());
1444 aSz.SetHeight(rDOP.yaPageGet());
1445 rFmt.SetFmtAttr(aSz);
1446 SvxLRSpaceItem aLR(rDOP.dxaLeftGet()+rDOP.dxaGutterGet(),
1447 rDOP.dxaRightGet(), 0, 0, RES_LR_SPACE);
1448 rFmt.SetFmtAttr(aLR);
1449 SvxULSpaceItem aUL(rDOP.dyaTopGet(), rDOP.dyaBottomGet(), RES_UL_SPACE);
1450 rFmt.SetFmtAttr(aUL);
1452 SwFtnInfo aInfo;
1453 aInfo = rOut.GetDoc().GetFtnInfo(); // Copy-Ctor privat
1454 // wo positioniert ? ( 0 == Section, 1 == Page,
1455 // 2 == beim Text -> Page, 3 == Doc )
1456 switch( rDOP.fpcGet() ){
1457 case 1:
1458 case 2: aInfo.ePos = FTNPOS_PAGE; break;
1459 default: aInfo.ePos = FTNPOS_CHAPTER; break;
1461 // Da Sw unter Chapter anscheinend was anderes versteht als PMW
1462 // hier also immer Doc !
1463 aInfo.eNum = FTNNUM_DOC;
1464 // wie neu nummerieren ?
1465 // SW-UI erlaubt Nummer nur bei FTNNUM_DOC
1466 if( rDOP.nFtnGet() > 0 && aInfo.eNum == FTNNUM_DOC )
1467 aInfo.nFtnOffset = rDOP.nFtnGet() - 1;
1468 rOut.GetDoc().SetFtnInfo( aInfo );
1472 ///////////////////////////////////////////////////////////////// Assoc
1473 void Ww1Assoc::Out(Ww1Shell& rOut)
1475 //~ mdt: fehlen: FileNext, Dot, DataDoc, HeaderDoc, Criteria1,
1476 // Criteria2, Criteria3, Criteria4, Criteria5, Criteria6, Criteria7
1477 SwDocShell *pDocShell(rOut.GetDoc().GetDocShell());
1478 OSL_ENSURE(pDocShell, "no SwDocShell");
1479 if (pDocShell) {
1480 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
1481 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
1482 uno::Reference<document::XDocumentProperties> xDocProps(
1483 xDPS->getDocumentProperties());
1484 OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
1485 if (xDocProps.is()) {
1486 xDocProps->setTitle( GetStr(Title) );
1487 xDocProps->setSubject( GetStr(Subject) );
1488 xDocProps->setDescription( GetStr(Comments) );
1489 xDocProps->setKeywords(
1490 ::comphelper::string::convertCommaSeparated( GetStr(KeyWords) ) );
1491 xDocProps->setAuthor( GetStr(Author) );
1492 xDocProps->setModifiedBy( GetStr(LastRevBy) );
1497 //////////////////////////////////////////////////////////// StyleSheet
1498 void Ww1StyleSheet::OutDefaults(Ww1Shell& rOut, Ww1Manager& rMan, sal_uInt16 stc)
1500 switch (stc){
1501 case 222: // Null
1502 rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE);
1503 rOut << SvxFontItem(rMan.GetFont(2));
1504 break;
1505 case 223: // annotation reference
1506 rOut << SvxFontHeightItem(160, 100, RES_CHRATR_FONTSIZE);
1507 break;
1508 case 224: // annotation text
1509 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1510 break;
1511 case 225: // table of contents 8
1512 case 226: // table of contents 7
1513 case 227: // table of contents 6
1514 case 228: // table of contents 5
1515 case 229: // table of contents 4
1516 case 230: // table of contents 3
1517 case 231: // table of contents 2
1518 case 232: // table of contents 1
1519 rOut << SvxLRSpaceItem(( 232 - stc ) * 720, 720, 0, 0, RES_LR_SPACE);
1520 // Tabulatoren fehlen noch !
1521 break;
1522 case 233: // index 7
1523 case 234: // und index 6
1524 case 235: // und index 5
1525 case 236: // und index 4
1526 case 237: // und index 3
1527 case 238: // und index 2
1528 rOut << SvxLRSpaceItem(( 239 - stc ) * 360, 0, 0, 0, RES_LR_SPACE);
1529 break;
1530 case 239: // index 1
1531 break;
1532 case 240: // line number
1533 break;
1534 case 241: // index heading
1535 break;
1536 case 242: // footer
1537 case 243:{ // ... und header
1538 SvxTabStopItem aAttr(RES_PARATR_TABSTOP);
1539 SvxTabStop aTabStop;
1540 aTabStop.GetTabPos() = 4535; // 8 cm
1541 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
1542 aAttr.Insert( aTabStop );
1543 aTabStop.GetTabPos() = 9071; // 16 cm
1544 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
1545 aAttr.Insert( aTabStop );
1546 rOut << aAttr;
1548 break;
1549 case 244: // footnote reference
1550 rOut << SvxFontHeightItem(160, 100, RES_CHRATR_FONTSIZE);
1551 rOut << SvxEscapementItem(6 * 100 / 24, 100, RES_CHRATR_ESCAPEMENT);
1552 break;
1553 case 245: // footnote text
1554 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1555 break;
1556 case 246: // heading 9
1557 case 247: // und heading 8
1558 case 248: // und heading 7
1559 rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE);
1560 rOut << SvxPostureItem(
1561 rOut.GetPostureItalic()?ITALIC_NONE:ITALIC_NORMAL, RES_CHRATR_POSTURE);
1562 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1563 break;
1564 case 249: // heading 6
1565 rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE);
1566 rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE);
1567 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1568 break;
1569 case 250: // heading 5
1570 rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE);
1571 rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT);
1572 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1573 break;
1574 case 251: // heading 4
1575 rOut << SvxLRSpaceItem(360, 0, 0, 0, RES_LR_SPACE);
1576 rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE);
1577 rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE);
1578 break;
1579 case 252: // heading 3
1580 rOut << SvxLRSpaceItem(360, 0, 0, 0, RES_LR_SPACE);
1581 rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT);
1582 rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE);
1583 break;
1584 case 253: // heading 2
1585 rOut << SvxULSpaceItem(120, 0, RES_UL_SPACE);
1586 rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT);
1587 rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE);
1588 rOut << SvxFontItem(rMan.GetFont(2));
1589 break;
1590 case 254: // heading 1
1591 rOut << SvxULSpaceItem(240, 0, RES_UL_SPACE);
1592 rOut << SvxWeightItem(rOut.GetWeightBold()?WEIGHT_NORMAL:WEIGHT_BOLD, RES_CHRATR_WEIGHT);
1593 rOut << SvxUnderlineItem(UNDERLINE_SINGLE, RES_CHRATR_UNDERLINE);
1594 rOut << SvxFontHeightItem(240, 100, RES_CHRATR_FONTSIZE);
1595 rOut << SvxFontItem(rMan.GetFont(2));
1596 break;
1597 case 255: // Normal indent
1598 rOut << SvxLRSpaceItem(720, 0, 0, 0, RES_LR_SPACE);
1599 break;
1600 case 0: // Normal
1601 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1602 break;
1603 default: // selbstdefiniert
1604 rOut << SvxFontHeightItem(200, 100, RES_CHRATR_FONTSIZE);
1605 break;
1609 void Ww1StyleSheet::OutOne(Ww1Shell& rOut, Ww1Manager& rMan, sal_uInt16 stc)
1611 const RES_POOL_COLLFMT_TYPE RES_NONE = RES_POOLCOLL_DOC_END;
1612 RES_POOL_COLLFMT_TYPE aType = RES_NONE;
1614 switch (stc)
1616 case 222: // Null
1617 aType = RES_POOLCOLL_TEXT; break; //???
1618 case 223: // annotation reference
1619 break;
1620 case 224: // annotation text
1621 break;
1622 case 225: // table of contents 8
1623 aType = RES_POOLCOLL_TOX_CNTNT8; break;
1624 case 226: // table of contents 7
1625 aType = RES_POOLCOLL_TOX_CNTNT7; break;
1626 case 227: // table of contents 6
1627 aType = RES_POOLCOLL_TOX_CNTNT6; break;
1628 case 228: // table of contents 5
1629 aType = RES_POOLCOLL_TOX_CNTNT5; break;
1630 case 229: // table of contents 4
1631 aType = RES_POOLCOLL_TOX_CNTNT4; break;
1632 case 230: // table of contents 3
1633 aType = RES_POOLCOLL_TOX_CNTNT3; break;
1634 case 231: // table of contents 2
1635 aType = RES_POOLCOLL_TOX_CNTNT2; break;
1636 case 232: // table of contents 1
1637 aType = RES_POOLCOLL_TOX_CNTNT1; break;
1638 case 233: // index 7
1639 break;
1640 case 234: // index 6
1641 break;
1642 case 235: // index 5
1643 break;
1644 case 236: // index 4
1645 break;
1646 case 237: // index 3
1647 aType = RES_POOLCOLL_TOX_IDX3; break;
1648 case 238: // index 2
1649 aType = RES_POOLCOLL_TOX_IDX2; break;
1650 case 239: // index 1
1651 aType = RES_POOLCOLL_TOX_IDX1; break;
1652 case 240: // line number
1653 break;
1654 case 241: // index heading
1655 break;
1656 case 242: // footer
1657 aType = RES_POOLCOLL_FOOTER; break;
1658 case 243: // header
1659 aType = RES_POOLCOLL_HEADER; break;
1660 case 244: // footnote reference
1661 break;
1662 case 245: // footnote text
1663 aType = RES_POOLCOLL_FOOTNOTE; break;
1664 case 246: // heading 9
1665 break;
1666 case 247: // heading 8
1667 break;
1668 case 248: // heading 7
1669 break;
1670 case 249: // heading 6
1671 break;
1672 case 250: // heading 5
1673 aType = RES_POOLCOLL_HEADLINE5; break;
1674 case 251: // heading 4
1675 aType = RES_POOLCOLL_HEADLINE4; break;
1676 case 252: // heading 3
1677 aType = RES_POOLCOLL_HEADLINE3; break;
1678 case 253: // heading 2
1679 aType = RES_POOLCOLL_HEADLINE2; break;
1680 case 254: // heading 1
1681 aType = RES_POOLCOLL_HEADLINE1; break;
1682 case 255: // Normal indent
1683 aType = RES_POOLCOLL_TEXT_IDENT; break;
1684 case 0: // Normal
1685 aType = RES_POOLCOLL_STANDARD; break;
1687 if (aType == RES_NONE)
1688 rOut.BeginStyle(stc, GetStyle(stc).GetName() );
1689 else
1690 rOut.BeginStyle(stc, aType);
1691 OutDefaults(rOut, rMan, stc);
1692 GetStyle(stc).Out(rOut, rMan);
1693 rOut.EndStyle();
1695 // OutOneWithBase() liest einen Style mit OutOne() einen Style ein
1696 // Jedoch liest er, wenn noch nicht geschehen, den Basisstyle rekursiv ein
1697 void Ww1StyleSheet::OutOneWithBase(Ww1Shell& rOut, Ww1Manager& rMan,
1698 sal_uInt16 stc, sal_uInt8* pbStopRecur )
1700 // SH: lineares Einlesen ist Scheisse, da dann BasedOn nicht gesetzt
1701 // werden kann und ausserdem Toggle- und Modify-Attrs (z.B. Tabs ) nicht gehen.
1703 Ww1Style& rSty = GetStyle(stc);
1704 sal_uInt16 nBase = rSty.GetnBase();
1705 if( nBase != stc
1706 && !rOut.IsStyleImported( nBase )
1707 && GetStyle(nBase).IsUsed()
1708 && !pbStopRecur[nBase] ){
1710 pbStopRecur[nBase] = 1;
1711 OutOneWithBase( rOut, rMan, nBase, pbStopRecur ); // Rekursiv
1713 OutOne( rOut, rMan, stc );
1716 void Ww1StyleSheet::Out(Ww1Shell& rOut, Ww1Manager& rMan)
1718 sal_uInt16 stc;
1719 sal_uInt8 bStopRecur[256];
1720 memset( bStopRecur, sal_False, sizeof(bStopRecur) );
1722 // 1. Durchlauf: Styles mit Basisstyles rekursiv
1723 for (stc=0;stc<Count();stc++)
1724 if (GetStyle(stc).IsUsed() && !rOut.IsStyleImported( stc ) )
1725 OutOneWithBase( rOut, rMan, stc, bStopRecur );
1727 // 2. Durchlauf: Follow-Styles
1728 for (stc=0;stc<Count();stc++){
1729 Ww1Style& rSty = GetStyle(stc);
1730 if ( rSty.IsUsed() ){
1731 sal_uInt16 nNext = rSty.GetnNext();
1732 if( nNext != stc && GetStyle(nNext).IsUsed() )
1733 rOut.NextStyle( stc, nNext );
1738 ////////////////////////////////////////////////////////////// Picture
1739 static sal_uLong GuessPicSize(W1_PIC* pPic)
1741 sal_uInt16 maxx = pPic->mfp.xExtGet();
1742 sal_uInt16 padx = ((maxx + 7) / 8) * 8;
1743 sal_uInt16 maxy = pPic->mfp.yExtGet();
1744 return 120L + (sal_uLong)padx * maxy;
1748 // folgende methode schreibt eine windows-.BMP-datei aus einem
1749 // embeddeten bild in ww-1 dateien
1750 // gelesen wird 4-bit format, geschrieben jedoch 8-bit.
1752 void Ww1Picture::WriteBmp(SvStream& rOut)
1754 long nSize = pPic->lcbGet() - (sizeof(*pPic)-sizeof(pPic->rgb));
1755 sal_uInt8* p = pPic->rgbGet();
1756 sal_uInt16 maxx = pPic->mfp.xExtGet();
1757 sal_uInt16 padx = ((maxx + 7) / 8) * 8;
1758 sal_uInt16 maxy = pPic->mfp.yExtGet();
1760 p+= sizeof(SVBT16); nSize -= sizeof(SVBT16);
1761 p+= sizeof(SVBT16); nSize -= sizeof(SVBT16);
1762 #if OSL_DEBUG_LEVEL > 0
1763 sal_uInt16 x = SVBT16ToShort(p);
1764 (void) x;
1765 #endif
1766 p+= sizeof(SVBT16); nSize -= sizeof(SVBT16);
1767 #if OSL_DEBUG_LEVEL > 0
1768 sal_uInt16 y = SVBT16ToShort(p);
1769 (void) y;
1770 #endif
1771 p+= sizeof(SVBT16); nSize -= sizeof(SVBT16);
1772 #if OSL_DEBUG_LEVEL > 0
1773 sal_uInt16 planes = SVBT16ToShort(p);
1774 (void) planes;
1775 #endif
1776 p+= sizeof(SVBT16); nSize -= sizeof(SVBT16);
1777 #if OSL_DEBUG_LEVEL > 0
1778 sal_uInt16 bitcount = SVBT16ToShort(p);
1779 (void) bitcount;
1780 #endif
1781 p+= sizeof(SVBT16); nSize -= sizeof(SVBT16);
1783 #if OSL_DEBUG_LEVEL > 0
1784 OSL_ENSURE(x==maxx, "Ww1Picture");
1785 OSL_ENSURE(y==maxy, "Ww1Picture");
1786 OSL_ENSURE(planes==1, "Ww1Picture");
1787 OSL_ENSURE(bitcount==4, "Ww1Picture");
1788 #endif
1790 OSL_ENSURE(16*3+padx*maxy/2==nSize, "Ww1Picture");
1792 SVBT32 tmpLong;
1793 SVBT16 tmpShort;
1794 SVBT8 tmpByte;
1795 #define wLong(n) \
1796 UInt32ToSVBT32(n, tmpLong); \
1797 if ((rOut.Write(tmpLong, sizeof(SVBT32))) != sizeof(SVBT32)) goto error;
1798 #define wShort(n) \
1799 ShortToSVBT16(n, tmpShort); \
1800 if ((rOut.Write(tmpShort, sizeof(SVBT16))) != sizeof(SVBT16)) goto error;
1801 #define wByte(n) \
1802 ByteToSVBT8(n, tmpByte); \
1803 if ((rOut.Write(tmpByte, sizeof(SVBT8))) != sizeof(SVBT8)) goto error;
1804 wByte('B'); wByte('M');
1805 wLong(54 + 4 * 16 + padx * maxy);
1806 wLong(0);
1807 wLong(54 + 4 * 16);
1808 wLong(40);
1809 wLong(maxx);
1810 wLong(maxy);
1811 wShort(1);
1812 wShort(8);
1813 wLong(0);
1814 wLong(0);
1815 wLong(0);
1816 wLong(0);
1817 wLong(16);
1818 wLong(16);
1819 sal_uInt16 i;
1820 for (i=0;nSize>0&&i<16;i++)
1822 wByte(*p);
1823 p++;
1824 nSize -= sizeof(sal_uInt8);
1825 wByte(*p);
1826 p++;
1827 nSize -= sizeof(sal_uInt8);
1828 wByte(*p);
1829 p++;
1830 nSize -= sizeof(sal_uInt8);
1831 wByte(0);
1833 OSL_ENSURE(padx*maxy/2==nSize, "Ww1Picture");
1834 sal_uInt16 j;
1836 sal_uInt8* pBuf = new sal_uInt8[padx];
1837 for (j=0;nSize>0&&j<maxy;j++)
1839 sal_uInt8* q = pBuf;
1840 for (i=0;nSize>0&&i<maxx;i+=2)
1842 *q++ = *p>>4;
1843 *q++ = *p&0xf;
1844 p++;
1845 nSize -= sizeof(sal_uInt8);
1847 for (;i<padx;i+=2)
1849 *q++ = 0;
1850 p++;
1851 nSize -= sizeof(sal_uInt8);
1853 if(rOut.Write(pBuf, padx) != padx){
1854 delete [] pBuf;
1855 goto error;
1858 delete [] pBuf;
1860 OSL_ENSURE(nSize==0, "Ww1Picture");
1861 #undef wLong
1862 #undef wShort
1863 #undef wByte
1864 rOut.Seek(0);
1865 return;
1866 error:
1870 void Ww1Picture::Out(Ww1Shell& rOut, Ww1Manager& /*rMan*/)
1872 Graphic* pGraphic = 0;
1873 sal_uInt16 mm;
1874 switch (mm = pPic->mfp.mmGet())
1876 case 8: // embedded metafile
1878 SvMemoryStream aOut(8192, 8192);
1879 aOut.Write(pPic->rgbGet(), pPic->lcbGet() -
1880 (sizeof(*pPic)-sizeof(pPic->rgb)));
1881 aOut.Seek(0);
1882 GDIMetaFile aWMF;
1883 if (ReadWindowMetafile( aOut, aWMF, NULL ) && aWMF.GetActionSize() > 0)
1885 aWMF.SetPrefMapMode(MapMode(MAP_100TH_MM));
1886 Size aOldSiz(aWMF.GetPrefSize());
1887 Size aNewSiz(pPic->mfp.xExtGet(), pPic->mfp.yExtGet());
1888 Fraction aFracX(aNewSiz.Width(), aOldSiz.Width());
1889 Fraction aFracY(aNewSiz.Height(), aOldSiz.Height());
1890 aWMF.Scale(aFracX, aFracY);
1891 aWMF.SetPrefSize(aNewSiz);
1892 pGraphic = new Graphic(aWMF);
1894 break;
1896 case 94: // embedded name SH:??? Was denn nun ? Embeddet oder Name ?
1897 case 98: // TIFF-Name
1899 String aDir( (sal_Char*)pPic->rgbGet(),
1900 (sal_uInt16)(pPic->lcbGet() - (sizeof(*pPic)-sizeof(pPic->rgb))),
1901 RTL_TEXTENCODING_MS_1252 );
1903 rOut.AddGraphic( aDir );
1905 break;
1906 case 97: // embedded bitmap
1908 sal_uLong nSiz = GuessPicSize(pPic);
1909 SvMemoryStream aOut(nSiz, 8192);
1910 WriteBmp(aOut);
1911 Bitmap aBmp;
1912 aOut >> aBmp;
1913 pGraphic = new Graphic(aBmp);
1915 default:
1916 OSL_ENSURE(pPic->mfp.mmGet() == 97, "Ww1Picture");
1918 if (pGraphic)
1919 rOut << *pGraphic;
1922 ////////////////////////////////////////////////////////// HeaderFooter
1923 void Ww1HeaderFooter::Start(Ww1Shell& rOut, Ww1Manager& rMan)
1925 // wird sowieso nur bei SEPs aufgerufen, keine weitere pruefung
1926 // noetig:
1927 if (!rMan.Pushed())
1929 while (++(*this))
1930 switch (eHeaderFooterMode)
1932 case FtnSep:
1933 break;
1934 case FtnFollowSep:
1935 break;
1936 case FtnNote:
1937 break;
1938 case EvenHeadL:
1939 break;
1940 case OddHeadL:
1942 sal_uLong begin = 0;
1943 sal_uLong end = 0;
1944 if (FillOddHeadL(begin, end))
1946 Ww1HddText* pText = new Ww1HddText(rMan.GetFib());
1947 pText->Seek(begin);
1948 pText->SetCount(end-begin);
1949 rOut.BeginHeader();
1950 rMan.Push1(pText, pText->Offset(rMan.GetFib()), begin,
1951 new Ww1HeaderFooterFields(rMan.GetFib()));
1952 rOut << rMan;
1953 rMan.Pop();
1954 rOut.EndHeaderFooter();
1955 return;
1958 break;
1959 case EvenFootL:
1960 break;
1961 case OddFootL:
1963 sal_uLong begin = 0;
1964 sal_uLong end = 0;
1965 if (FillOddFootL(begin, end))
1967 Ww1HddText* pText = new Ww1HddText(rMan.GetFib());
1968 pText->Seek(begin);
1969 pText->SetCount(end-begin);
1970 rOut.BeginFooter();
1971 rMan.Push1(pText, pText->Offset(rMan.GetFib()), begin,
1972 new Ww1HeaderFooterFields(rMan.GetFib()));
1973 rOut << rMan;
1974 rMan.Pop();
1975 rOut.EndHeaderFooter();
1976 return;
1979 break;
1980 case FirstHeadL:
1981 break;
1982 default:
1983 break;
1988 void Ww1HeaderFooter::Stop(Ww1Shell& rOut, Ww1Manager& rMan, sal_Unicode&)
1990 if (!rMan.Pushed() && eHeaderFooterMode != None)
1992 Start(rOut, rMan);
1997 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */