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