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