xref: /trunk/main/sw/source/filter/rtf/swparrtf.cxx (revision 870262e3)
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 
25 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
26 #include <hintids.hxx>
27 #include <stack>
28 #include <tools/errinf.hxx>
29 #include <tools/stream.hxx>
30 #include <svl/itemiter.hxx>
31 #include <svtools/rtftoken.h>
32 #include <svl/intitem.hxx>
33 #include <editeng/fhgtitem.hxx>
34 #include <editeng/ulspitem.hxx>
35 #include <editeng/tstpitem.hxx>
36 #include <editeng/lspcitem.hxx>
37 #include <editeng/lrspitem.hxx>
38 #include <editeng/escpitem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/frmdiritem.hxx>
41 #include <editeng/hyznitem.hxx>
42 #include <fmtpdsc.hxx>
43 #include <fmtfld.hxx>
44 #include <fmthdft.hxx>
45 #include <fmtcntnt.hxx>
46 #include <txtftn.hxx>
47 #include <fmtclds.hxx>
48 #include <fmtftn.hxx>
49 #include <fmtfsize.hxx>
50 #include <fmtflcnt.hxx>
51 #include <fmtanchr.hxx>
52 #include <frmatr.hxx>
53 #include <docstat.hxx>
54 #include <swtable.hxx>
55 #include <shellio.hxx>
56 #include <swtypes.hxx>
57 #include <ndtxt.hxx>
58 #include <doc.hxx>
59 #include <docary.hxx>
60 #include <pam.hxx>
61 #include <mdiexp.hxx>           // ...Percent()
62 #include <swparrtf.hxx>
63 #include <charfmt.hxx>
64 #include <pagedesc.hxx>
65 #include <ftninfo.hxx>
66 #include <docufld.hxx>
67 #include <flddat.hxx>
68 #include <fltini.hxx>
69 #include <fchrfmt.hxx>
70 #include <paratr.hxx>
71 #include <section.hxx>
72 #include <fmtclbl.hxx>
73 #include <viewsh.hxx>
74 #include <shellres.hxx>
75 #include <hfspacingitem.hxx>
76 #include <tox.hxx>
77 #include <swerror.h>
78 #include <cmdid.h>
79 #include <statstr.hrc>          // ResId fuer Statusleiste
80 #include <SwStyleNameMapper.hxx>
81 #include <tblsel.hxx>           // SwSelBoxes
82 #include <docsh.hxx>
83 #include <fmtlsplt.hxx> // SwLayoutSplit
84 #include <editeng/keepitem.hxx>
85 #include <svx/svdopath.hxx>
86 #include <svx/svdorect.hxx>
87 #include <fmtsrnd.hxx>
88 #include <fmtfollowtextflow.hxx>
89 #include <svx/svdmodel.hxx>
90 #include <svx/svdpage.hxx>
91 #include <editeng/opaqitem.hxx>
92 #include "svx/svdograf.hxx"
93 #include <svx/xflclit.hxx>
94 #include <svx/xlnwtit.hxx>
95 #include <svx/svdoutl.hxx>
96 #include <editeng/outlobj.hxx>
97 #include <editeng/paperinf.hxx>
98 #include <tools/stream.hxx>
99 #include <basegfx/polygon/b2dpolygon.hxx>
100 #include <basegfx/polygon/b2dpolypolygon.hxx>
101 #include <basegfx/range/b2drange.hxx>
102 #include <vcl/salbtype.hxx>     // FRound
103 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
104 #include <drawdoc.hxx>
105 
106 using namespace ::com::sun::star;
107 
108 // einige Hilfs-Funktionen
109 // char
GetSize(const SfxItemSet & rSet,sal_Bool bInP=sal_True)110 inline const SvxFontHeightItem& GetSize(const SfxItemSet& rSet,sal_Bool bInP=sal_True)
111     { return (const SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE,bInP); }
GetLRSpace(const SfxItemSet & rSet,sal_Bool bInP=sal_True)112 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_Bool bInP=sal_True)
113     { return (const SvxLRSpaceItem&)rSet.Get( RES_LR_SPACE,bInP); }
114 
115 /*  */
116 
ImportRTF()117 extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportRTF()
118 {
119     return new RtfReader();
120 }
121 
122 // Aufruf fuer die allg. Reader-Schnittstelle
Read(SwDoc & rDoc,const String & rBaseURL,SwPaM & rPam,const String &)123 sal_uLong RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String &)
124 {
125     if( !pStrm )
126     {
127         ASSERT( sal_False, "RTF-Read ohne Stream" );
128         return ERR_SWG_READ_ERROR;
129     }
130 
131     //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
132     //              Kapitelnummer. Darum hier explizit abschalten
133     //              weil das Default jetzt wieder auf AN ist.
134     if( !bInsertMode )
135     {
136         Reader::SetNoOutlineNum( rDoc );
137 
138         // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
139         Reader::ResetFrmFmts( rDoc );
140     }
141 
142     sal_uLong nRet = 0;
143     SwDocShell *pDocShell(rDoc.GetDocShell());
144     DBG_ASSERT(pDocShell, "no SwDocShell");
145     uno::Reference<document::XDocumentProperties> xDocProps;
146     if (pDocShell) {
147         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
148             pDocShell->GetModel(), uno::UNO_QUERY_THROW);
149         xDocProps.set(xDPS->getDocumentProperties());
150     }
151 
152     SvParserRef xParser = new SwRTFParser( &rDoc, xDocProps,
153                                 rPam, *pStrm, rBaseURL, !bInsertMode );
154     SvParserState eState = xParser->CallParser();
155     if( SVPAR_PENDING != eState && SVPAR_ACCEPTED != eState )
156     {
157         String sErr( String::CreateFromInt32( xParser->GetLineNr() ));
158         sErr += ',';
159         sErr += String::CreateFromInt32( xParser->GetLinePos() );
160 
161         nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr,
162                                     ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR );
163     }
164 
165 
166     return nRet;
167 }
168 
Read(SvStream * pStream,SwDoc & rDoc,const String & rBaseURL,SwPaM & rPam)169 sal_uLong RtfReader::Read(SvStream* pStream, SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam)
170 {
171     pStrm = pStream;
172     return Read(rDoc, rBaseURL, rPam, rBaseURL);
173 }
174 
SwRTFParser(SwDoc * pD,uno::Reference<document::XDocumentProperties> i_xDocProps,const SwPaM & rCrsr,SvStream & rIn,const String & rBaseURL,int bReadNewDoc)175 SwRTFParser::SwRTFParser(SwDoc* pD,
176         uno::Reference<document::XDocumentProperties> i_xDocProps,
177         const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL,
178         int bReadNewDoc) :
179     SvxRTFParser(pD->GetAttrPool(), rIn, i_xDocProps, bReadNewDoc),
180     maParaStyleMapper(*pD),
181     maCharStyleMapper(*pD),
182     maSegments(*this),
183     maInsertedTables(*pD),
184     mpBookmarkStart(0),
185     mpRedlineStack(0),
186     pAuthorInfos(0),
187     pGrfAttrSet(0),
188     pTableNode(0),
189     pOldTblNd(0),
190     pSttNdIdx(0),
191     pRegionEndIdx(0),
192     pDoc(pD),
193     pRelNumRule(new SwRelNumRuleSpaces(*pD, static_cast< sal_Bool >(bReadNewDoc))),
194     pRedlineInsert(0),
195     pRedlineDelete(0),
196     sBaseURL( rBaseURL ),
197     nAktPageDesc(0),
198     nAktFirstPageDesc(0),
199     m_nCurrentBox(0),
200     nInsTblRow(USHRT_MAX),
201     nNewNumSectDef(USHRT_MAX),
202     nRowsToRepeat(0),
203     // --> OD 2008-12-22 #i83368#
204     mbReadCellWhileReadSwFly( false ),
205     // <--
206     bTrowdRead(0),
207     nReadFlyDepth(0),
208     nZOrder(0)
209 {
210     mbIsFootnote = mbReadNoTbl = bReadSwFly = bSwPageDesc = bStyleTabValid =
211     bInPgDscTbl = bNewNumList = false;
212     bFirstContinue = true;
213     bContainsPara = false;
214     bContainsTablePara = false;
215     bNestedField = false;
216     bForceNewTable = false;
217 
218     pPam = new SwPaM( *rCrsr.GetPoint() );
219     SetInsPos( SwxPosition( pPam ) );
220     SetChkStyleAttr( 0 != bReadNewDoc );
221     SetCalcValue( sal_False );
222     SetReadDocInfo( sal_True );
223 
224     // diese sollen zusaetzlich ueber \pard zurueck gesetzt werden
225     sal_uInt16 temp;
226     temp = RES_TXTATR_CHARFMT;      AddPlainAttr( temp );
227     temp = RES_PAGEDESC;            AddPardAttr( temp );
228     temp = RES_BREAK;               AddPardAttr( temp );
229     temp = RES_PARATR_NUMRULE;      AddPardAttr( temp );
230     temp = FN_PARAM_NUM_LEVEL;          AddPardAttr( temp );
231 }
232 
233 // Aufruf des Parsers
CallParser()234 SvParserState SwRTFParser::CallParser()
235 {
236     mbReadNoTbl = false;
237     bFirstContinue = true;
238 
239     rInput.Seek(STREAM_SEEK_TO_BEGIN);
240     rInput.ResetError();
241 
242     mpRedlineStack = new sw::util::RedlineStack(*pDoc);
243 
244     return SvxRTFParser::CallParser();
245 }
246 
lcl_UsedPara(SwPaM & rPam)247 bool lcl_UsedPara(SwPaM &rPam)
248 {
249     const SwCntntNode* pCNd;
250     const SfxItemSet* pSet;
251     if( rPam.GetPoint()->nContent.GetIndex() ||
252         ( 0 != ( pCNd = rPam.GetCntntNode()) &&
253           0 != ( pSet = pCNd->GetpSwAttrSet()) &&
254          ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False ) ||
255            SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False ))))
256         return true;
257     return false;
258 }
259 
Continue(int nToken)260 void SwRTFParser::Continue( int nToken )
261 {
262     if( bFirstContinue )
263     {
264         bFirstContinue = sal_False;
265 
266         if (IsNewDoc())
267         {
268             //
269             // COMPATIBILITY FLAGS START
270             //
271             pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX, true);
272             pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true);
273             pDoc->set(IDocumentSettingAccess::TAB_COMPAT, true);
274             pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, true);
275             pDoc->set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true);
276             pDoc->set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true);
277             pDoc->set(IDocumentSettingAccess::ADD_EXT_LEADING, true);
278             pDoc->set(IDocumentSettingAccess::OLD_NUMBERING, false);
279             pDoc->set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false );
280             pDoc->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, false);
281             pDoc->set(IDocumentSettingAccess::OLD_LINE_SPACING, false);
282             pDoc->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true);
283             pDoc->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false);
284             pDoc->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false);
285             pDoc->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true);
286             pDoc->set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // --> FME 2005-08-11 #i53199#
287             // --> FME 2006-02-10 #131283#
288             pDoc->set(IDocumentSettingAccess::TABLE_ROW_KEEP, true);
289             pDoc->set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true);
290 
291             //
292             // COMPATIBILITY FLAGS END
293             //
294         }
295 
296         // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
297         pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() );
298         if( !IsNewDoc() )       // in ein Dokument einfuegen ?
299         {
300             const SwPosition* pPos = pPam->GetPoint();
301             SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
302 
303             pDoc->SplitNode( *pPos, false );
304 
305             *pSttNdIdx = pPos->nNode.GetIndex()-1;
306             pDoc->SplitNode( *pPos, false );
307 
308             SwPaM aInsertionRangePam( *pPos );
309 
310             pPam->Move( fnMoveBackward );
311 
312             // #106634# split any redline over the insertion point
313             aInsertionRangePam.SetMark();
314             *aInsertionRangePam.GetPoint() = *pPam->GetPoint();
315             aInsertionRangePam.Move( fnMoveBackward );
316             pDoc->SplitRedline( aInsertionRangePam );
317 
318             pDoc->SetTxtFmtColl( *pPam, pDoc->GetTxtCollFromPool
319                                  ( RES_POOLCOLL_STANDARD, false ));
320 
321             // verhinder das einlesen von Tabellen in Fussnoten / Tabellen
322             sal_uLong nNd = pPos->nNode.GetIndex();
323             mbReadNoTbl = 0 != pSttNd->FindTableNode() ||
324                         ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
325                         pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
326         }
327 
328         // Laufbalken anzeigen, aber nur bei synchronem Call
329         sal_uLong nCurrPos = rInput.Tell();
330         rInput.Seek(STREAM_SEEK_TO_END);
331         rInput.ResetError();
332         ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell());
333         rInput.Seek( nCurrPos );
334         rInput.ResetError();
335     }
336 
337     SvxRTFParser::Continue( nToken );
338 
339     if( SVPAR_PENDING == GetStatus() )
340         return ;                // weiter gehts beim naechsten mal
341 
342     pRelNumRule->SetNumRelSpaces( *pDoc );
343 
344     // den Start wieder korrigieren
345     if( !IsNewDoc() && pSttNdIdx->GetIndex() )
346     {
347         //die Flys muessen zuerst zurecht gerueckt werden, denn sonst wird
348         // ein am 1. Absatz verankerter Fly falsch eingefuegt
349         if( SVPAR_ACCEPTED == eState )
350         {
351             if( aFlyArr.Count() )
352                 SetFlysInDoc();
353             pRelNumRule->SetOultineRelSpaces( *pSttNdIdx, pPam->GetPoint()->nNode );
354         }
355 
356         SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode();
357         SwNodeIndex aNxtIdx( *pSttNdIdx );
358         if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx ))
359         {
360             xub_StrLen nStt = pTxtNode->GetTxt().Len();
361             // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
362             if( pPam->GetPoint()->nNode == aNxtIdx )
363             {
364                 pPam->GetPoint()->nNode = *pSttNdIdx;
365                 pPam->GetPoint()->nContent.Assign( pTxtNode, nStt );
366             }
367 
368 #ifdef DBG_UTIL
369 // !!! sollte nicht moeglich sein, oder ??
370 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_True ).nNode.GetIndex(),
371             "Pam.Bound1 steht noch im Node" );
372 ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_False ).nNode.GetIndex(),
373             "Pam.Bound2 steht noch im Node" );
374 
375 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_True ).nNode.GetIndex() )
376 {
377     xub_StrLen nCntPos = pPam->GetBound( sal_True ).nContent.GetIndex();
378     pPam->GetBound( sal_True ).nContent.Assign( pTxtNode,
379                     pTxtNode->GetTxt().Len() + nCntPos );
380 }
381 if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_False ).nNode.GetIndex() )
382 {
383     xub_StrLen nCntPos = pPam->GetBound( sal_False ).nContent.GetIndex();
384     pPam->GetBound( sal_False ).nContent.Assign( pTxtNode,
385                     pTxtNode->GetTxt().Len() + nCntPos );
386 }
387 #endif
388             // Zeichen Attribute beibehalten!
389             SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode();
390             if( pTxtNode->GetTxt().Len() )
391                 pDelNd->FmtToTxtAttr( pTxtNode );
392             else
393                 pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() );
394             pTxtNode->JoinNext();
395         }
396     }
397 
398     if( SVPAR_ACCEPTED == eState )
399     {
400         // den letzen Bereich wieder zumachen
401         if( pRegionEndIdx )
402         {
403             // JP 06.01.00: Task 71411 - the last section in WW are not a
404             //              balanced Section.
405             if( !GetVersionNo() )
406             {
407                 SwSectionNode* pSectNd = pRegionEndIdx->GetNode().
408                                     StartOfSectionNode()->GetSectionNode();
409                 if( pSectNd )
410                     pSectNd->GetSection().GetFmt()->SetFmtAttr(
411                                     SwFmtNoBalancedColumns( sal_True ) );
412             }
413 
414             DelLastNode();
415             pPam->GetPoint()->nNode = *pRegionEndIdx;
416             pPam->Move( fnMoveForward, fnGoNode );
417             delete pRegionEndIdx, pRegionEndIdx = 0;
418         }
419 
420         sal_uInt16 nPageDescOffset = pDoc->GetPageDescCnt();
421         maSegments.InsertSegments(IsNewDoc());
422         UpdatePageDescs(*pDoc, nPageDescOffset);
423         //$flr folloing garbe collecting code has been moved from the previous procedure
424         //     UpdatePageDescs to here in order to fix bug #117882#
425         rtfSections::myrDummyIter aDEnd = maSegments.maDummyPageNos.rend();
426         for (rtfSections::myrDummyIter aI = maSegments.maDummyPageNos.rbegin(); aI != aDEnd; ++aI)
427             pDoc->DelPageDesc(*aI);
428 
429         if( aFlyArr.Count() )
430             SetFlysInDoc();
431 
432         // jetzt noch den letzten ueberfluessigen Absatz loeschen
433         SwPosition* pPos = pPam->GetPoint();
434         if( !pPos->nContent.GetIndex() )
435         {
436             SwTxtNode* pAktNd;
437             sal_uLong nNodeIdx = pPos->nNode.GetIndex();
438             if( IsNewDoc() )
439             {
440                 SwNode* pTmp = pDoc->GetNodes()[ nNodeIdx -1 ];
441                 if( pTmp->IsCntntNode() && !pTmp->FindTableNode() )
442                 {
443                     // --> FME 2006-02-15 #131200# Do not delete the paragraph
444                     // if it has anchored objects:
445                     bool bAnchoredObjs = false;
446                     const SwSpzFrmFmts* pFrmFmts = pDoc->GetSpzFrmFmts();
447                     if ( pFrmFmts && pFrmFmts->Count() )
448                     {
449                         for ( sal_uInt16 nI = pFrmFmts->Count(); nI; --nI )
450                         {
451                             const SwFmtAnchor & rAnchor = (*pFrmFmts)[ nI - 1 ]->GetAnchor();
452                             if ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
453                                 (FLY_AT_CHAR == rAnchor.GetAnchorId()))
454                             {
455                                 const SwPosition * pObjPos = rAnchor.GetCntntAnchor();
456                                 if ( pObjPos && nNodeIdx == pObjPos->nNode.GetIndex() )
457                                 {
458                                     bAnchoredObjs = true;
459                                     break;
460                                 }
461                             }
462                         }
463                     }
464                     // <--
465 
466                     if ( !bAnchoredObjs )
467                         DelLastNode();
468                 }
469             }
470             else if (0 != (pAktNd = pDoc->GetNodes()[nNodeIdx]->GetTxtNode()))
471             {
472                 if( pAktNd->CanJoinNext( &pPos->nNode ))
473                 {
474                     SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode();
475                     pPos->nContent.Assign( pNextNd, 0 );
476                     pPam->SetMark(); pPam->DeleteMark();
477                     pNextNd->JoinPrev();
478                 }
479                 else if( !pAktNd->GetTxt().Len() &&
480                         pAktNd->StartOfSectionIndex()+2 <
481                         pAktNd->EndOfSectionIndex() )
482                 {
483                     pPos->nContent.Assign( 0, 0 );
484                     pPam->SetMark(); pPam->DeleteMark();
485                     pDoc->GetNodes().Delete( pPos->nNode, 1 );
486                     pPam->Move( fnMoveBackward );
487                 }
488             }
489         }
490         // nun noch das SplitNode vom Ende aufheben
491         else if( !IsNewDoc() )
492         {
493             if( pPos->nContent.GetIndex() )     // dann gabs am Ende kein \par,
494                 pPam->Move( fnMoveForward, fnGoNode );  // als zum naechsten Node
495             SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode();
496             SwNodeIndex aPrvIdx( pPos->nNode );
497             if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) &&
498                 *pSttNdIdx <= aPrvIdx )
499             {
500                 // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
501                 // usw. sind im pTxtNode angemeldet, so dass der bestehen
502                 // bleiben MUSS.
503 
504                 // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
505                 // Absatzattribute und die Vorlage uebernehmen!
506                 SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode();
507                 pTxtNode->ChgFmtColl( pPrev->GetTxtColl() );
508                 pTxtNode->FmtToTxtAttr( pPrev );
509                 pTxtNode->ResetAllAttr();
510 
511                 if( pPrev->HasSwAttrSet() )
512                     pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() );
513 
514                 if( &pPam->GetBound(sal_True).nNode.GetNode() == pPrev )
515                     pPam->GetBound(sal_True).nContent.Assign( pTxtNode, 0 );
516                 if( &pPam->GetBound(sal_False).nNode.GetNode() == pPrev )
517                     pPam->GetBound(sal_False).nContent.Assign( pTxtNode, 0 );
518 
519                 pTxtNode->JoinPrev();
520             }
521         }
522     }
523     delete pSttNdIdx, pSttNdIdx = 0;
524     delete pRegionEndIdx, pRegionEndIdx = 0;
525     RemoveUnusedNumRules();
526 
527     pDoc->SetUpdateExpFldStat(true);
528     pDoc->SetInitDBFields(true);
529 
530     // Laufbalken bei asynchronen Call nicht einschalten !!!
531     ::EndProgress( pDoc->GetDocShell() );
532 }
533 
SetCols(SwFrmFmt & rFmt,const rtfSection & rSection,sal_uInt16 nNettoWidth)534 bool rtfSections::SetCols(SwFrmFmt &rFmt, const rtfSection &rSection,
535     sal_uInt16 nNettoWidth)
536 {
537     //sprmSCcolumns - Anzahl der Spalten - 1
538     sal_uInt16 nCols = static_cast< sal_uInt16 >(rSection.NoCols());
539 
540     if (nCols < 2)
541         return false;                   // keine oder bloedsinnige Spalten
542 
543     SwFmtCol aCol;                      // Erzeuge SwFmtCol
544 
545     //sprmSDxaColumns   - Default-Abstand 1.25 cm
546     sal_uInt16 nColSpace = static_cast< sal_uInt16 >(rSection.StandardColSeperation());
547 
548     aCol.Init( nCols, nColSpace, nNettoWidth );
549 
550     // not SFEvenlySpaced
551     if (rSection.maPageInfo.maColumns.size())
552     {
553         aCol._SetOrtho(false);
554         sal_uInt16 nWishWidth = 0, nHalfPrev = 0;
555         for (sal_uInt16 n=0, i=0;
556              (static_cast<size_t>(n)+1) < rSection.maPageInfo.maColumns.size() && i < nCols;
557              n += 2, ++i)
558         {
559             SwColumn* pCol = aCol.GetColumns()[ i ];
560             pCol->SetLeft( nHalfPrev );
561             sal_uInt16 nSp = static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n+1 ]);
562             nHalfPrev = nSp / 2;
563             pCol->SetRight( nSp - nHalfPrev );
564             pCol->SetWishWidth( static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n ]) +
565                 pCol->GetLeft() + pCol->GetRight());
566             nWishWidth = nWishWidth + pCol->GetWishWidth();
567         }
568         aCol.SetWishWidth( nWishWidth );
569     }
570 
571     rFmt.SetFmtAttr(aCol);
572     return true;
573 }
574 
SetPage(SwPageDesc & rInPageDesc,SwFrmFmt & rFmt,const rtfSection & rSection,bool bIgnoreCols)575 void rtfSections::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
576     const rtfSection &rSection, bool bIgnoreCols)
577 {
578     // 1. Orientierung
579     rInPageDesc.SetLandscape(rSection.IsLandScape());
580 
581     // 2. Papiergroesse
582     SwFmtFrmSize aSz(rFmt.GetFrmSize());
583     aSz.SetWidth(rSection.GetPageWidth());
584     aSz.SetHeight(rSection.GetPageHeight());
585     rFmt.SetFmtAttr(aSz);
586 
587     rFmt.SetFmtAttr(
588         SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
589 
590     if (!bIgnoreCols)
591     {
592         SetCols(rFmt, rSection, static_cast< sal_uInt16 >(rSection.GetPageWidth() -
593             rSection.GetPageLeft() - rSection.GetPageRight()));
594     }
595 
596     rFmt.SetFmtAttr(rSection.maPageInfo.maBox);
597 }
598 
HasHeader(const SwFrmFmt & rFmt)599 bool HasHeader(const SwFrmFmt &rFmt)
600 {
601     const SfxPoolItem *pHd;
602     if (SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, false, &pHd))
603         return ((const SwFmtHeader *)(pHd))->IsActive();
604     return false;
605 }
606 
HasFooter(const SwFrmFmt & rFmt)607 bool HasFooter(const SwFrmFmt &rFmt)
608 {
609     const SfxPoolItem *pFt;
610     if (SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, false, &pFt))
611         return ((const SwFmtFooter *)(pFt))->IsActive();
612     return false;
613 }
614 
GetPageULData(const rtfSection & rSection,bool bFirst,rtfSections::wwULSpaceData & rData)615 void rtfSections::GetPageULData(const rtfSection &rSection, bool bFirst,
616     rtfSections::wwULSpaceData& rData)
617 {
618     short nWWUp     = static_cast< short >(rSection.maPageInfo.mnMargtsxn);
619     short nWWLo     = static_cast< short >(rSection.maPageInfo.mnMargbsxn);
620     short nWWHTop   = static_cast< short >(rSection.maPageInfo.mnHeadery);
621     short nWWFBot   = static_cast< short >(rSection.maPageInfo.mnFootery);
622 
623     if (bFirst)
624     {
625         if (
626             rSection.mpTitlePage && HasHeader(rSection.mpTitlePage->GetMaster())
627            )
628         {
629             rData.bHasHeader = true;
630         }
631     }
632     else
633     {
634         if (rSection.mpPage &&
635                (
636                HasHeader(rSection.mpPage->GetMaster())
637                || HasHeader(rSection.mpPage->GetLeft())
638                )
639            )
640         {
641             rData.bHasHeader = true;
642         }
643     }
644 
645     if( rData.bHasHeader )
646     {
647         rData.nSwUp  = nWWHTop;             // Header -> umrechnen, see ww8par6.cxx
648 
649         if ( nWWUp > 0 && nWWUp >= nWWHTop )
650             rData.nSwHLo = nWWUp - nWWHTop;
651         else
652             rData.nSwHLo = 0;
653 
654         if (rData.nSwHLo < cMinHdFtHeight)
655             rData.nSwHLo = cMinHdFtHeight;
656     }
657     else // kein Header -> Up einfach uebernehmen
658         rData.nSwUp = Abs(nWWUp);
659 
660     if (bFirst)
661     {
662         if (
663                 rSection.mpTitlePage &&
664                 HasFooter(rSection.mpTitlePage->GetMaster())
665            )
666         {
667             rData.bHasFooter = true;
668         }
669     }
670     else
671     {
672         if (rSection.mpPage &&
673            (
674                HasFooter(rSection.mpPage->GetMaster())
675                || HasFooter(rSection.mpPage->GetLeft())
676            )
677            )
678         {
679             rData.bHasFooter = true;
680         }
681     }
682 
683     if( rData.bHasFooter )
684     {
685         rData.nSwLo = nWWFBot;              // Footer -> Umrechnen
686         if ( nWWLo > 0 && nWWLo >= nWWFBot )
687             rData.nSwFUp = nWWLo - nWWFBot;
688         else
689             rData.nSwFUp = 0;
690 
691         if (rData.nSwFUp < cMinHdFtHeight)
692             rData.nSwFUp = cMinHdFtHeight;
693     }
694     else // kein Footer -> Lo einfach uebernehmen
695         rData.nSwLo = Abs(nWWLo);
696 }
697 
SetPageULSpaceItems(SwFrmFmt & rFmt,rtfSections::wwULSpaceData & rData)698 void rtfSections::SetPageULSpaceItems(SwFrmFmt &rFmt,
699     rtfSections::wwULSpaceData& rData)
700 {
701     if (rData.bHasHeader)               // ... und Header-Lower setzen
702     {
703         //Kopfzeilenhoehe minimal sezten
704         if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
705         {
706             pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
707             SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
708             aHdUL.SetLower( rData.nSwHLo - cMinHdFtHeight );
709             pHdFmt->SetFmtAttr(aHdUL);
710             pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
711                 RES_HEADER_FOOTER_EAT_SPACING, true));
712         }
713     }
714 
715     if (rData.bHasFooter)               // ... und Footer-Upper setzen
716     {
717         if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
718         {
719             pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
720             SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
721             aFtUL.SetUpper( rData.nSwFUp - cMinHdFtHeight );
722             pFtFmt->SetFmtAttr(aFtUL);
723             pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
724                 RES_HEADER_FOOTER_EAT_SPACING, true));
725         }
726     }
727 
728     SvxULSpaceItem aUL(rData.nSwUp, rData.nSwLo, RES_UL_SPACE ); // Page-UL setzen
729     rFmt.SetFmtAttr(aUL);
730 }
731 
SetSegmentToPageDesc(const rtfSection & rSection,bool bTitlePage,bool bIgnoreCols)732 void rtfSections::SetSegmentToPageDesc(const rtfSection &rSection,
733     bool bTitlePage, bool bIgnoreCols)
734 {
735     SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage;
736 
737 //    SetNumberingType(rSection, rPage);
738 
739     SwFrmFmt &rFmt = rPage.GetMaster();
740 //    mrReader.SetDocumentGrid(rFmt, rSection);
741 
742     wwULSpaceData aULData;
743     GetPageULData(rSection, bTitlePage, aULData);
744     SetPageULSpaceItems(rFmt, aULData);
745 
746     SetPage(rPage, rFmt, rSection, bIgnoreCols);
747 
748     UseOnPage ePage = rPage.ReadUseOn();
749     if(ePage & nsUseOnPage::PD_ALL)
750     {
751         SwFrmFmt &rFmtLeft = rPage.GetLeft();
752         SetPageULSpaceItems(rFmtLeft, aULData);
753         SetPage(rPage, rFmtLeft, rSection, bIgnoreCols);
754     }
755 
756 }
757 
CopyFrom(const SwPageDesc & rFrom,SwPageDesc & rDest)758 void rtfSections::CopyFrom(const SwPageDesc &rFrom, SwPageDesc &rDest)
759 {
760     UseOnPage ePage = rFrom.ReadUseOn();
761     rDest.WriteUseOn(ePage);
762 
763     mrReader.pDoc->CopyHeader(rFrom.GetMaster(), rDest.GetMaster());
764     SwFrmFmt &rDestFmt = rDest.GetMaster();
765     rDestFmt.SetFmtAttr(rFrom.GetMaster().GetHeader());
766     mrReader.pDoc->CopyHeader(rFrom.GetLeft(), rDest.GetLeft());
767     mrReader.pDoc->CopyFooter(rFrom.GetMaster(), rDest.GetMaster());
768     mrReader.pDoc->CopyFooter(rFrom.GetLeft(), rDest.GetLeft());
769 }
770 
MoveFrom(SwPageDesc & rFrom,SwPageDesc & rDest)771 void rtfSections::MoveFrom(SwPageDesc &rFrom, SwPageDesc &rDest)
772 {
773     UseOnPage ePage = rFrom.ReadUseOn();
774     rDest.WriteUseOn(ePage);
775 
776     SwFrmFmt &rDestMaster = rDest.GetMaster();
777     SwFrmFmt &rFromMaster = rFrom.GetMaster();
778     rDestMaster.SetFmtAttr(rFromMaster.GetHeader());
779     rDestMaster.SetFmtAttr(rFromMaster.GetFooter());
780     //rFromMaster.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
781     //rFromMaster.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
782 
783     SwFrmFmt &rDestLeft = rDest.GetLeft();
784     SwFrmFmt &rFromLeft = rFrom.GetLeft();
785     rDestLeft.SetFmtAttr(rFromLeft.GetHeader());
786     rDestLeft.SetFmtAttr(rFromLeft.GetFooter());
787     //rFromLeft.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882#
788     //rFromLeft.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882#
789 }
790 
SetHdFt(rtfSection & rSection)791 void rtfSections::SetHdFt(rtfSection &rSection)
792 {
793     ASSERT(rSection.mpPage, "makes no sense to call without a main page");
794     if (rSection.mpPage && rSection.maPageInfo.mpPageHdFt)
795     {
796         if (rSection.maPageInfo.mbPageHdFtUsed)
797         {
798             MoveFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
799             rSection.maPageInfo.mbPageHdFtUsed = false;
800             rSection.maPageInfo.mpPageHdFt = rSection.mpPage;
801         }
802         else
803             CopyFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage);
804     }
805 
806     if (rSection.mpTitlePage && rSection.maPageInfo.mpTitlePageHdFt)
807     {
808         if (rSection.maPageInfo.mbTitlePageHdFtUsed)
809         {
810             MoveFrom(*rSection.maPageInfo.mpTitlePageHdFt,
811                     *rSection.mpTitlePage);
812             rSection.maPageInfo.mbTitlePageHdFtUsed = false;
813             rSection.maPageInfo.mpTitlePageHdFt = rSection.mpTitlePage;
814         }
815         else
816         {
817             CopyFrom(*rSection.maPageInfo.mpTitlePageHdFt,
818                     *rSection.mpTitlePage);
819         }
820     }
821 }
822 
InsertSection(SwPaM & rMyPaM,rtfSection & rSection)823 SwSectionFmt *rtfSections::InsertSection(SwPaM& rMyPaM, rtfSection &rSection)
824 {
825     SwSectionData aSectionData(CONTENT_SECTION,
826             mrReader.pDoc->GetUniqueSectionName());
827 
828     SfxItemSet aSet( mrReader.pDoc->GetAttrPool(), aFrmFmtSetRange );
829 
830     sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
831     aSet.Put(SvxFrameDirectionItem(
832         nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
833 
834     rSection.mpSection =
835         mrReader.pDoc->InsertSwSection( rMyPaM, aSectionData, 0, &aSet );
836     ASSERT(rSection.mpSection, "section not inserted!");
837     if (!rSection.mpSection)
838         return 0;
839 
840     SwPageDesc *pPage = 0;
841     mySegrIter aEnd = maSegments.rend();
842     for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
843     {
844         pPage = aIter->mpPage;
845         if (pPage)
846             break;
847     }
848 
849     ASSERT(pPage, "no page outside this section!");
850 
851     if (!pPage)
852         pPage = &mrReader.pDoc->_GetPageDesc(0);
853 
854     if (!pPage)
855         return 0;
856 
857     SwFrmFmt& rFmt = pPage->GetMaster();
858     const SwFmtFrmSize&   rSz = rFmt.GetFrmSize();
859     const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
860     SwTwips nWidth = rSz.GetWidth();
861     long nLeft  = rLR.GetTxtLeft();
862     long nRight = rLR.GetRight();
863 
864     SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
865     ASSERT(pFmt, "impossible");
866     if (!pFmt)
867         return 0;
868     SetCols(*pFmt, rSection, (sal_uInt16)(nWidth - nLeft - nRight) );
869 
870     return pFmt;
871 }
872 
InsertSegments(bool bNewDoc)873 void rtfSections::InsertSegments(bool bNewDoc)
874 {
875     sal_uInt16 nDesc(0);
876     mySegIter aEnd = maSegments.end();
877     mySegIter aStart = maSegments.begin();
878     for (mySegIter aIter = aStart; aIter != aEnd; ++aIter)
879     {
880         mySegIter aNext = aIter+1;
881 
882         bool bInsertSection = aIter != aStart ? aIter->IsContinous() : false;
883 
884         if (!bInsertSection)
885         {
886             /*
887              If a cont section follow this section then we won't be
888              creating a page desc with 2+ cols as we cannot host a one
889              col section in a 2+ col pagedesc and make it look like
890              word. But if the current section actually has columns then
891              we are forced to insert a section here as well as a page
892              descriptor.
893             */
894 
895             /*
896              Note for the future:
897              If we want to import "protected sections" the here is
898              where we would also test for that and force a section
899              insertion if that was true.
900             */
901             bool bIgnoreCols = false;
902             if (aNext != aEnd && aNext->IsContinous())
903             {
904                 bIgnoreCols = true;
905                 if (aIter->NoCols() > 1)
906                     bInsertSection = true;
907             }
908 
909             if (aIter->HasTitlePage())
910             {
911                 if (bNewDoc && aIter == aStart)
912                 {
913                     aIter->mpTitlePage =
914                         mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_FIRST);
915                 }
916                 else
917                 {
918                     sal_uInt16 nPos = mrReader.pDoc->MakePageDesc(
919                         ViewShell::GetShellRes()->GetPageDescName(nDesc)
920                         , 0, false);
921                     aIter->mpTitlePage = &mrReader.pDoc->_GetPageDesc(nPos);
922                 }
923                 ASSERT(aIter->mpTitlePage, "no page!");
924                 if (!aIter->mpTitlePage)
925                     continue;
926 
927                 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
928             }
929 
930             if (!bNewDoc && aIter == aStart)
931                 continue;
932             else if (bNewDoc && aIter == aStart)
933             {
934                 aIter->mpPage =
935                     mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD);
936             }
937             else
938             {
939                 sal_uInt16 nPos = mrReader.pDoc->MakePageDesc(
940                     ViewShell::GetShellRes()->GetPageDescName(nDesc,
941                         false, aIter->HasTitlePage()),
942                         aIter->mpTitlePage, false);
943                 aIter->mpPage = &mrReader.pDoc->_GetPageDesc(nPos);
944             }
945             ASSERT(aIter->mpPage, "no page!");
946             if (!aIter->mpPage)
947                 continue;
948 
949             SetHdFt(*aIter);
950 
951             if (aIter->mpTitlePage)
952                 SetSegmentToPageDesc(*aIter, true, bIgnoreCols);
953             SetSegmentToPageDesc(*aIter, false, bIgnoreCols);
954 
955             SwFmtPageDesc aPgDesc(aIter->HasTitlePage() ?
956                  aIter->mpTitlePage : aIter->mpPage);
957 
958             if (aIter->mpTitlePage)
959                 aIter->mpTitlePage->SetFollow(aIter->mpPage);
960 
961             if (aIter->PageRestartNo() ||
962                 ((aIter == aStart) && aIter->PageStartAt() != 1))
963                 aPgDesc.SetNumOffset( static_cast< sal_uInt16 >(aIter->PageStartAt()) );
964 
965             /*
966             If its a table here, apply the pagebreak to the table
967             properties, otherwise we add it to the para at this
968             position
969             */
970             if (aIter->maStart.GetNode().IsTableNode())
971             {
972                 SwTable& rTable =
973                     aIter->maStart.GetNode().GetTableNode()->GetTable();
974                 SwFrmFmt* pApply = rTable.GetFrmFmt();
975                 ASSERT(pApply, "impossible");
976                 if (pApply)
977                     pApply->SetFmtAttr(aPgDesc);
978             }
979             else
980             {
981                 SwPosition aPamStart(aIter->maStart);
982                 aPamStart.nContent.Assign(
983                     aIter->maStart.GetNode().GetCntntNode(), 0);
984                 SwPaM aPage(aPamStart);
985 
986                 mrReader.pDoc->InsertPoolItem(aPage, aPgDesc, 0);
987             }
988             ++nDesc;
989         }
990 
991         SwTxtNode* pTxtNd = 0;
992         if (bInsertSection)
993         {
994             SwPaM aSectPaM(*mrReader.pPam);
995             SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode);
996             if (aNext != aEnd)
997             {
998                 aAnchor = aNext->maStart;
999                 aSectPaM.GetPoint()->nNode = aAnchor;
1000                 aSectPaM.GetPoint()->nContent.Assign(
1001                     aNext->maStart.GetNode().GetCntntNode(), 0);
1002                 aSectPaM.Move(fnMoveBackward);
1003             }
1004 
1005             const SwPosition* pPos  = aSectPaM.GetPoint();
1006             SwTxtNode const*const pSttNd = pPos->nNode.GetNode().GetTxtNode();
1007             const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0;
1008             if (pTableNd)
1009             {
1010                 pTxtNd =
1011                     mrReader.pDoc->GetNodes().MakeTxtNode(aAnchor,
1012                     mrReader.pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT ));
1013 
1014                 aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd);
1015                 aSectPaM.GetPoint()->nContent.Assign(
1016                     aSectPaM.GetCntntNode(), 0);
1017             }
1018 
1019             aSectPaM.SetMark();
1020 
1021             aSectPaM.GetPoint()->nNode = aIter->maStart;
1022             aSectPaM.GetPoint()->nContent.Assign(
1023                 aSectPaM.GetCntntNode(), 0);
1024 
1025             SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter);
1026             //The last section if continuous is always unbalanced
1027             if (aNext == aEnd && pRet)
1028                 pRet->SetFmtAttr(SwFmtNoBalancedColumns(true));
1029         }
1030 
1031         if (pTxtNd)
1032         {
1033             SwNodeIndex aIdx(*pTxtNd);
1034             SwPosition aPos(aIdx);
1035             SwPaM aTest(aPos);
1036             mrReader.pDoc->DelFullPara(aTest);
1037             pTxtNd = 0;
1038         }
1039     }
1040 }
1041 
1042 namespace sw{
1043     namespace util{
1044 
InsertedTableClient(SwTableNode & rNode)1045 InsertedTableClient::InsertedTableClient(SwTableNode & rNode)
1046 {
1047     rNode.Add(this);
1048 }
1049 
GetTableNode()1050 SwTableNode * InsertedTableClient::GetTableNode()
1051 {
1052     return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
1053 }
1054 
InsertedTablesManager(const SwDoc & rDoc)1055 InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc)
1056     : mbHasRoot(rDoc.GetCurrentLayout())	//swmod 080218
1057 {
1058 }
1059 
DelAndMakeTblFrms()1060 void InsertedTablesManager::DelAndMakeTblFrms()
1061 {
1062     if (!mbHasRoot)
1063         return;
1064     TblMapIter aEnd = maTables.end();
1065     for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter)
1066     {
1067         // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames
1068         // neu erzeugt
1069         SwTableNode *pTable = aIter->first->GetTableNode();
1070         ASSERT(pTable, "Why no expected table");
1071         if (pTable)
1072         {
1073             SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt();
1074 
1075             if (pFrmFmt != NULL)
1076             {
1077                 SwNodeIndex *pIndex = aIter->second;
1078                 pTable->DelFrms();
1079                 pTable->MakeFrms(pIndex);
1080             }
1081         }
1082     }
1083 }
1084 
InsertTable(SwTableNode & rTableNode,SwPaM & rPaM)1085 void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
1086 {
1087     if (!mbHasRoot)
1088         return;
1089     //Associate this tablenode with this after position, replace an //old
1090     //node association if necessary
1091 
1092     InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
1093 
1094     maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode)));
1095 }
1096 }
1097 }
1098 
~SwRTFParser()1099 SwRTFParser::~SwRTFParser()
1100 {
1101     maInsertedTables.DelAndMakeTblFrms();
1102     mpRedlineStack->closeall(*pPam->GetPoint());
1103     delete mpRedlineStack;
1104 
1105     delete pSttNdIdx;
1106     delete pRegionEndIdx;
1107     delete pPam;
1108     delete pRelNumRule;
1109 
1110     if (aFlyArr.Count())
1111         aFlyArr.DeleteAndDestroy( 0, aFlyArr.Count() );
1112 
1113     if (pGrfAttrSet)
1114         DELETEZ( pGrfAttrSet );
1115 
1116     DELETEZ( pAuthorInfos );
1117 }
1118 
1119 //i19718
ReadShpRslt()1120 void SwRTFParser::ReadShpRslt()
1121 {
1122     int nToken;
1123     while ('}' != (nToken = GetNextToken() ) && IsParserWorking())
1124     {
1125         switch(nToken)
1126         {
1127             case RTF_PAR:
1128                 break;
1129             default:
1130                 NextToken(nToken);
1131                 break;
1132         }
1133     }
1134     SkipToken(-1);
1135 }
1136 
ReadShpTxt(String & s)1137 void SwRTFParser::ReadShpTxt(String& s)
1138 {
1139   int nToken;
1140   int level=1;
1141   s.AppendAscii("{\\rtf");
1142   while (level>0 && IsParserWorking())
1143     {
1144       nToken = GetNextToken();
1145       switch(nToken)
1146     {
1147     case RTF_SN:
1148     case RTF_SV:
1149       SkipGroup();
1150       break;
1151     case RTF_TEXTTOKEN:
1152       s.Append(aToken);
1153       break;
1154     case '{':
1155       level++;
1156       s.Append(String::CreateFromAscii("{"));
1157       break;
1158     case '}':
1159       level--;
1160       s.Append(String::CreateFromAscii("}"));
1161       break;
1162     default:
1163       s.Append(aToken);
1164       if (bTokenHasValue) {
1165         s.Append(String::CreateFromInt64(nTokenValue));
1166       }
1167       s.Append(String::CreateFromAscii(" "));
1168       break;
1169     }
1170     }
1171   SkipToken(-1);
1172 }
1173 
1174 /*
1175  * #127429#. Very basic support for the "Buchhalternase".
1176  */
ReadDrawingObject()1177 void SwRTFParser::ReadDrawingObject()
1178 {
1179     int nToken;
1180     int level;
1181     level=1;
1182     Rectangle aRect;
1183     ::basegfx::B2DPolygon aPolygon;
1184     ::basegfx::B2DPoint aPoint;
1185     bool bPolygonActive(false);
1186 
1187     while (level>0 && IsParserWorking())
1188     {
1189         nToken = GetNextToken();
1190         switch(nToken)
1191         {
1192             case '}':
1193                 level--;
1194                 break;
1195             case '{':
1196                 level++;
1197                 break;
1198             case RTF_DPX:
1199                 aRect.setX(nTokenValue);
1200                 break;
1201             case RTF_DPXSIZE:
1202                 aRect.setWidth(nTokenValue);
1203                 break;
1204             case RTF_DPY:
1205                 aRect.setY(nTokenValue);
1206                 break;
1207             case RTF_DPYSIZE:
1208                 aRect.setHeight(nTokenValue);
1209                 break;
1210             case RTF_DPPOLYCOUNT:
1211                 bPolygonActive = true;
1212                 break;
1213             case RTF_DPPTX:
1214                 aPoint.setX(nTokenValue);
1215                 break;
1216             case RTF_DPPTY:
1217                 aPoint.setY(nTokenValue);
1218 
1219                 if(bPolygonActive)
1220                 {
1221                     aPolygon.append(aPoint);
1222                 }
1223 
1224                 break;
1225             default:
1226                 break;
1227         }
1228     }
1229     SkipToken(-1);
1230     /*
1231     const Point aPointC1( 0, 0 );
1232     const Point aPointC2( 100, 200 );
1233     const Point aPointC3( 300, 400 );
1234     XPolygon aPolygonC(3);
1235     aPolygonC[0] = aPointC1;
1236     aPolygonC[1] = aPointC2;
1237     aPolygonC[2] = aPointC3;
1238     */
1239     if(bPolygonActive && aPolygon.count())
1240     {
1241         SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aPolygon));
1242         SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1243         SwFmtSurround aSur( SURROUND_PARALLEL );
1244         aSur.SetContour( false );
1245         aSur.SetOutside(true);
1246         aFlySet.Put( aSur );
1247         SwFmtFollowTextFlow aFollowTextFlow( sal_False );
1248         aFlySet.Put( aFollowTextFlow );
1249         /*
1250         sw::util::SetLayer aSetLayer(*pDoc);
1251         aSetLayer.SendObjectToHeaven(*pStroke);
1252         */
1253         SwFmtAnchor aAnchor( FLY_AT_PARA );
1254         aAnchor.SetAnchor( pPam->GetPoint() );
1255         aFlySet.Put( aAnchor );
1256 
1257         /*
1258         text::RelOrientation::FRAME,          // Absatz inkl. Raender
1259         text::RelOrientation::PRINT_AREA,     // Absatz ohne Raender
1260         text::RelOrientation::CHAR,       // an einem Zeichen
1261         text::RelOrientation::PAGE_LEFT,  // im linken Seitenrand
1262         text::RelOrientation::PAGE_RIGHT,   // im rechten Seitenrand
1263         text::RelOrientation::FRAME_LEFT,   // im linken Absatzrand
1264         text::RelOrientation::FRAME_RIGHT,  // im rechten Absatzrand
1265         text::RelOrientation::PAGE_FRAME, // Seite inkl. Raender, bei seitengeb. identisch mit text::RelOrientation::FRAME
1266         text::RelOrientation::PAGE_PRINT_AREA,    // Seite ohne Raender, bei seitengeb. identisch mit text::RelOrientation::PRTAREA
1267         // OD 11.11.2003 #i22341#
1268         text::RelOrientation::TEXT_LINE,  // vertical relative to top of text line, only for to-character
1269                         // anchored objects.
1270 
1271 
1272             text::HoriOrientation::NONE,      //Der Wert in nYPos gibt die RelPos direkt an.
1273         text::HoriOrientation::RIGHT,     //Der Rest ist fuer automatische Ausrichtung.
1274         text::HoriOrientation::CENTER,
1275         text::HoriOrientation::LEFT,
1276         text::HoriOrientation::INSIDE,
1277         text::HoriOrientation::OUTSIDE,
1278         text::HoriOrientation::FULL,          //Spezialwert fuer Tabellen
1279         text::HoriOrientation::LEFT_AND_WIDTH  //Auch fuer Tabellen
1280         */
1281         SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1282         aFlySet.Put( aHori );
1283         /*
1284         text::VertOrientation::NONE,  //Der Wert in nYPos gibt die RelPos direkt an.
1285         text::VertOrientation::TOP,   //Der Rest ist fuer automatische Ausrichtung.
1286         text::VertOrientation::CENTER,
1287         text::VertOrientation::BOTTOM,
1288         text::VertOrientation::CHAR_TOP,      //Ausrichtung _nur_ fuer Zeichengebundene Rahmen
1289         text::VertOrientation::CHAR_CENTER,   //wie der Name jew. sagt wird der RefPoint des Rahmens
1290         text::VertOrientation::CHAR_BOTTOM,   //entsprechend auf die Oberkante, Mitte oder Unterkante
1291         text::VertOrientation::LINE_TOP,      //der Zeile gesetzt. Der Rahmen richtet sich  dann
1292         text::VertOrientation::LINE_CENTER,   //entsprechend aus.
1293         text::VertOrientation::LINE_BOTTOM
1294         */
1295         SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1296         aFlySet.Put( aVert );
1297 
1298         pDoc->GetOrCreateDrawModel();
1299         SwDrawModel* pDrawModel  = pDoc->GetDrawModel();
1300         SdrPage* pDrawPg = pDrawModel->GetPage(0);
1301         pDrawPg->InsertObject(pStroke, 0);
1302 
1303         pStroke->SetSnapRect(aRect);
1304 
1305         /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet );
1306     }
1307 }
1308 
InsertShpObject(SdrObject * pStroke,int _nZOrder)1309 void SwRTFParser::InsertShpObject(SdrObject* pStroke, int _nZOrder)
1310 {
1311         SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
1312         SwFmtSurround aSur( SURROUND_THROUGHT );
1313         aSur.SetContour( false );
1314         aSur.SetOutside(true);
1315         aFlySet.Put( aSur );
1316         SwFmtFollowTextFlow aFollowTextFlow( sal_False );
1317         aFlySet.Put( aFollowTextFlow );
1318 
1319         SwFmtAnchor aAnchor( FLY_AT_PARA );
1320         aAnchor.SetAnchor( pPam->GetPoint() );
1321         aFlySet.Put( aAnchor );
1322 
1323 
1324         SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1325         aFlySet.Put( aHori );
1326 
1327         SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME );
1328         aFlySet.Put( aVert );
1329 
1330         aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
1331 
1332         pDoc->GetOrCreateDrawModel();
1333         SwDrawModel* pDrawModel  = pDoc->GetDrawModel();
1334         SdrPage* pDrawPg = pDrawModel->GetPage(0);
1335         pDrawPg->InsertObject(pStroke);
1336         pDrawPg->SetObjectOrdNum(pStroke->GetOrdNum(), _nZOrder);
1337         /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet );
1338 }
1339 
rotate(const::basegfx::B2DPoint & rStart,const::basegfx::B2DPoint & rEnd)1340 ::basegfx::B2DPoint rotate(const ::basegfx::B2DPoint& rStart, const ::basegfx::B2DPoint& rEnd)
1341 {
1342     const ::basegfx::B2DVector aVector(rStart - rEnd);
1343     return ::basegfx::B2DPoint(aVector.getY() + rEnd.getX(), -aVector.getX() + rEnd.getY());
1344 }
1345 
1346 
ReadShapeObject()1347 void SwRTFParser::ReadShapeObject()
1348 {
1349     int nToken;
1350     int level;
1351     level=1;
1352     ::basegfx::B2DPoint aPointLeftTop;
1353     ::basegfx::B2DPoint aPointRightBottom;
1354     String sn;
1355     sal_Int32 shapeType=-1;
1356     Graphic aGrf;
1357     bool bGrfValid=false;
1358     bool fFilled=true;
1359     Color fillColor(255, 255, 255);
1360     bool fLine=true;
1361     int lineWidth=9525/360;
1362     String shpTxt;
1363     bool bshpTxt=false;
1364     int txflTextFlow=0;
1365     ::rtl::OUString sDescription, sName;
1366 
1367 
1368     while (level>0 && IsParserWorking())
1369     {
1370         nToken = GetNextToken();
1371         switch(nToken)
1372         {
1373             case '}':
1374                 level--;
1375                 break;
1376             case '{':
1377                 level++;
1378                 break;
1379             case RTF_SHPLEFT:
1380                 aPointLeftTop.setX(nTokenValue);
1381                 break;
1382             case RTF_SHPTOP:
1383                 aPointLeftTop.setY(nTokenValue);
1384                 break;
1385             case RTF_SHPBOTTOM:
1386                 aPointRightBottom.setY(nTokenValue);
1387                 break;
1388             case RTF_SHPRIGHT:
1389                 aPointRightBottom.setX(nTokenValue);
1390                 break;
1391             case RTF_SN:
1392                 nToken = GetNextToken();
1393                 ASSERT(nToken==RTF_TEXTTOKEN, "expected name");
1394                 sn=aToken;
1395                 break;
1396             case RTF_SV:
1397                 nToken = GetNextToken();
1398                 if (nToken==RTF_TEXTTOKEN)
1399                 {
1400                     if (sn.EqualsAscii("shapeType"))
1401                     {
1402                         shapeType=aToken.ToInt32();
1403 
1404                     } else if (sn.EqualsAscii("fFilled"))
1405                     {
1406                         fFilled=aToken.ToInt32();
1407 
1408                     } else if (sn.EqualsAscii("fLine"))
1409                     {
1410                             fLine=aToken.ToInt32();
1411                     } else if (sn.EqualsAscii("lineWidth"))
1412                     {
1413                             lineWidth=aToken.ToInt32()/360;
1414 
1415                     } else if (sn.EqualsAscii("fillColor"))
1416                     {
1417                         sal_uInt32 nColor=aToken.ToInt32();
1418                         fillColor=Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
1419                     }else if (sn.EqualsAscii("txflTextFlow"))
1420                       {
1421                         txflTextFlow=aToken.ToInt32();
1422                       }
1423                     else if (sn.EqualsAscii("wzDescription"))
1424                     {
1425                         sDescription = aToken;
1426                     }
1427                     else if(sn.EqualsAscii("wzName"))
1428                     {
1429                         sName = aToken;
1430                     }
1431                 }
1432                 break;
1433             case RTF_PICT:
1434                 {
1435                         SvxRTFPictureType aPicType;
1436                         bGrfValid=ReadBmpData( aGrf, aPicType );
1437                 }
1438                 break;
1439             case RTF_SHPRSLT:
1440                 if (shapeType!=1 && shapeType!=20 && shapeType!=75)
1441                 {
1442                     ReadShpRslt();
1443                 }
1444                 break;
1445                      case RTF_SHPTXT:
1446                ReadShpTxt(shpTxt);
1447                bshpTxt=true;
1448                break;
1449 
1450             default:
1451                 break;
1452         }
1453     }
1454     SkipToken(-1);
1455 
1456     SdrObject* pSdrObject = 0;
1457     switch(shapeType)
1458     {
1459         case 202: /* Text Box */
1460     case 1: /* Rectangle */
1461         {
1462             ::basegfx::B2DRange aRange(aPointLeftTop);
1463             aRange.expand(aPointRightBottom);
1464 
1465           if (txflTextFlow==2) {
1466             const ::basegfx::B2DPoint a(rotate(aRange.getMinimum(), aRange.getCenter()));
1467             const ::basegfx::B2DPoint b(rotate(aRange.getMaximum(), aRange.getCenter()));
1468 
1469             aRange.reset();
1470             aRange.expand(a);
1471             aRange.expand(b);
1472           }
1473 
1474             const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1475             SdrRectObj* pStroke = new SdrRectObj(aRect);
1476             pSdrObject = pStroke;
1477             pStroke->SetSnapRect(aRect);
1478             pDoc->GetOrCreateDrawModel(); // create model
1479             InsertShpObject(pStroke, this->nZOrder++);
1480             SfxItemSet aSet(pStroke->GetMergedItemSet());
1481             if (fFilled)
1482             {
1483                 aSet.Put(XFillStyleItem(XFILL_SOLID));
1484                 aSet.Put(XFillColorItem( String(), fillColor ) );
1485             }
1486             else
1487             {
1488                 aSet.Put(XFillStyleItem(XFILL_NONE));
1489             }
1490             if (!fLine) {
1491               aSet.Put(XLineStyleItem(XLINE_NONE));
1492             } else {
1493               aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1494             }
1495 
1496             pStroke->SetMergedItemSet(aSet);
1497             if (bshpTxt) {
1498               SdrOutliner& rOutliner=pDoc->GetDrawModel()->GetDrawOutliner(pStroke);
1499               rOutliner.Clear();
1500               ByteString bs(shpTxt, RTL_TEXTENCODING_ASCII_US);
1501               SvMemoryStream aStream((sal_Char*)bs.GetBuffer(), bs.Len(), STREAM_READ);
1502               rOutliner.Read(aStream, String::CreateFromAscii(""), EE_FORMAT_RTF);
1503               OutlinerParaObject* pParaObject=rOutliner.CreateParaObject();
1504               pStroke->NbcSetOutlinerParaObject(pParaObject);
1505               //delete pParaObject;
1506               rOutliner.Clear();
1507             }
1508             if (txflTextFlow==2) {
1509               long nAngle = 90;
1510               double a = nAngle*100*nPi180;
1511               pStroke->Rotate(pStroke->GetCurrentBoundRect().Center(), nAngle*100, sin(a), cos(a) );
1512 
1513             }
1514 
1515         }
1516         break;
1517     case 20: /* Line */
1518         {
1519             ::basegfx::B2DPolygon aLine;
1520             aLine.append(aPointLeftTop);
1521             aLine.append(aPointRightBottom);
1522 
1523             SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aLine));
1524             pSdrObject = pStroke;
1525             //pStroke->SetSnapRect(aRect);
1526 
1527             InsertShpObject(pStroke, this->nZOrder++);
1528             SfxItemSet aSet(pStroke->GetMergedItemSet());
1529             if (!fLine) {
1530               aSet.Put(XLineStyleItem(XLINE_NONE));
1531             } else {
1532               aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width
1533             }
1534 
1535             pStroke->SetMergedItemSet(aSet);
1536         }
1537         break;
1538     case 75 : /* Picture */
1539         if (bGrfValid) {
1540             ::basegfx::B2DRange aRange(aPointLeftTop);
1541             aRange.expand(aPointRightBottom);
1542             const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
1543 
1544             SdrRectObj* pStroke = new SdrGrafObj(aGrf);
1545             pSdrObject = pStroke;
1546             pStroke->SetSnapRect(aRect);
1547 
1548             InsertShpObject(pStroke, this->nZOrder++);
1549         }
1550     }
1551     if( pSdrObject )
1552     {
1553         pSdrObject->SetDescription(sDescription);
1554         pSdrObject->SetTitle(sName);
1555     }
1556 }
1557 
1558 extern void sw3io_ConvertFromOldField( SwDoc& rDoc, sal_uInt16& rWhich,
1559                                 sal_uInt16& rSubType, sal_uLong &rFmt,
1560                                 sal_uInt16 nVersion );
1561 
ReadRevTbl()1562 sal_uInt16 SwRTFParser::ReadRevTbl()
1563 {
1564     // rStr.Erase( 0 );
1565     int nNumOpenBrakets = 1, nToken;        // die erste wurde schon vorher erkannt !!
1566     sal_uInt16 nAuthorTableIndex = 0;
1567 
1568     while( nNumOpenBrakets && IsParserWorking() )
1569     {
1570         switch( nToken = GetNextToken() )
1571         {
1572         case '}':   --nNumOpenBrakets;  break;
1573         case '{':
1574             {
1575                 if( RTF_IGNOREFLAG != GetNextToken() )
1576                     nToken = SkipToken( -1 );
1577                 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
1578                     nToken = SkipToken( -2 );
1579                 else
1580                 {
1581                     ReadUnknownData();
1582                     nToken = GetNextToken();
1583                     if( '}' != nToken )
1584                         eState = SVPAR_ERROR;
1585                     break;
1586                 }
1587                 ++nNumOpenBrakets;
1588             }
1589             break;
1590 
1591         case RTF_TEXTTOKEN:
1592             aToken.EraseTrailingChars(';');
1593 
1594             sal_uInt16 nSWId = pDoc->InsertRedlineAuthor(aToken);
1595             // Store matchpair
1596             if( !pAuthorInfos )
1597                 pAuthorInfos = new sw::util::AuthorInfos;
1598             sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthorTableIndex, nSWId );
1599             if( 0 == pAuthorInfos->Insert( pAutorInfo ) )
1600                 delete pAutorInfo;
1601 
1602             aRevTbl.push_back(aToken);
1603             nAuthorTableIndex++;
1604             break;
1605         }
1606     }
1607     SkipToken( -1 );
1608     return nAuthorTableIndex;
1609 }
1610 
NextToken(int nToken)1611 void SwRTFParser::NextToken( int nToken )
1612 {
1613     sal_uInt16 eDateFmt;
1614 
1615     switch( nToken )
1616     {
1617     case RTF_FOOTNOTE:
1618     {
1619         //We can only insert a footnote if we're not inside a footnote. e.g.
1620         //#i7713#
1621 
1622         // in insert mode it's also possible to be inside of a footnote!
1623         bool bInsertIntoFootnote = false;
1624         if( !IsNewDoc() )
1625         {
1626             SwStartNode* pSttNode = pPam->GetNode()->StartOfSectionNode();
1627             while(pSttNode && pSttNode->IsSectionNode())
1628             {
1629                 pSttNode = pSttNode->StartOfSectionNode();
1630             }
1631             if( SwFootnoteStartNode == pSttNode->GetStartNodeType() )
1632                 bInsertIntoFootnote = true;
1633         }
1634         if (!mbIsFootnote && !bInsertIntoFootnote)
1635         {
1636             ReadHeaderFooter( nToken );
1637             SkipToken( -1 );        // Klammer wieder zurueck
1638         }
1639     }
1640     break;
1641     case RTF_SWG_PRTDATA:
1642         ReadPrtData();
1643         break;
1644     case RTF_XE:
1645         ReadXEField();
1646         break;
1647     case RTF_FIELD:
1648         ReadField();
1649         break;
1650     case RTF_SHPRSLT:
1651         ReadShpRslt();
1652         break;
1653     case RTF_DO:
1654         ReadDrawingObject();
1655         break;
1656     case RTF_SHP:
1657         ReadShapeObject();
1658         break;
1659     case RTF_SHPPICT:
1660     case RTF_PICT:
1661         ReadBitmapData();
1662         break;
1663 #ifdef READ_OLE_OBJECT
1664     case RTF_OBJECT:
1665         ReadOLEData();
1666         break;
1667 #endif
1668     case RTF_TROWD:                 ReadTable( nToken );        break;
1669     case RTF_PGDSCTBL:
1670         if( !IsNewDoc() )
1671             SkipPageDescTbl();
1672         else
1673             ReadPageDescTbl();
1674         break;
1675     case RTF_LISTTABLE:             ReadListTable();            break;
1676     case RTF_LISTOVERRIDETABLE:     ReadListOverrideTable();    break;
1677 
1678     case RTF_LISTTEXT:
1679         GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1680         SkipGroup();
1681         break;
1682 
1683     case RTF_PN:
1684         if( bNewNumList )
1685             SkipGroup();
1686         else
1687         {
1688             bStyleTabValid = sal_True;
1689             if (SwNumRule* pRule = ReadNumSecLevel( nToken ))
1690             {
1691                 GetAttrSet().Put( SwNumRuleItem( pRule->GetName() ));
1692 
1693                 if( SFX_ITEM_SET != GetAttrSet().GetItemState( FN_PARAM_NUM_LEVEL, sal_False ))
1694                     GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
1695             }
1696         }
1697         break;
1698 
1699 
1700     case RTF_BKMKSTART:
1701         if(RTF_TEXTTOKEN == GetNextToken())
1702             mpBookmarkStart = new BookmarkPosition(*pPam);
1703         else
1704             SkipToken(-1);
1705 
1706         SkipGroup();
1707         break;
1708 
1709     case RTF_BKMKEND:
1710         if(RTF_TEXTTOKEN == GetNextToken())
1711         {
1712             const String& sBookmark = aToken;
1713             KeyCode aEmptyKeyCode;
1714             if (mpBookmarkStart)
1715             {
1716                 BookmarkPosition aBookmarkEnd(*pPam);
1717                 SwPaM aBookmarkRegion(  mpBookmarkStart->maMkNode, mpBookmarkStart->mnMkCntnt,
1718                                         aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt);
1719                 if (*mpBookmarkStart == aBookmarkEnd)
1720                     aBookmarkRegion.DeleteMark();
1721                 pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK);
1722             }
1723             delete mpBookmarkStart, mpBookmarkStart = 0;
1724         }
1725         else
1726             SkipToken(-1);
1727 
1728         SkipGroup();
1729         break;
1730 
1731 
1732     case RTF_PNSECLVL:{
1733         if( bNewNumList)
1734             SkipGroup();
1735         else
1736             ReadNumSecLevel( nToken );
1737         break;
1738                       }
1739 
1740     case RTF_PNTEXT:
1741     case RTF_NONSHPPICT:
1742         SkipGroup();
1743         break;
1744 
1745     case RTF_DEFFORMAT:
1746     case RTF_DEFTAB:
1747     case RTF_DEFLANG:
1748         // sind zwar Dok-Controls, werden aber manchmal auch vor der
1749         // Font/Style/Color-Tabelle gesetzt!
1750         SvxRTFParser::NextToken( nToken );
1751         break;
1752 
1753     case RTF_PAGE:
1754         if (pTableNode==NULL) { //#117410#: A \page command within a table is ignored by Word.
1755             if (lcl_UsedPara(*pPam))
1756                 InsertPara();
1757             CheckInsNewTblLine();
1758             pDoc->InsertPoolItem(*pPam,
1759                 SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1760         }
1761         break;
1762 
1763     case RTF_SECT:
1764         ReadSectControls( nToken );
1765         break;
1766     case RTF_CELL:
1767         // --> OD 2008-12-22 #i83368#
1768         mbReadCellWhileReadSwFly = bReadSwFly;
1769         // <--
1770         if (CantUseTables())
1771             InsertPara();
1772         else
1773         {
1774             // Tabelle nicht mehr vorhanden ?
1775             if (USHRT_MAX != nInsTblRow && !pTableNode)
1776                 NewTblLine();               // evt. Line copieren
1777             GotoNextBox();
1778         }
1779         break;
1780 
1781     case RTF_ROW:
1782         bTrowdRead=false;
1783         if (!CantUseTables())
1784         {
1785             // aus der Line raus
1786             m_nCurrentBox = 0;
1787             pTableNode = 0;
1788             // noch in der Tabelle drin?
1789             SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
1790             const SwTableNode* pTblNd = rIdx.GetNode().FindTableNode();
1791             if( pTblNd )
1792             {
1793                 // search the end of this row
1794                 const SwStartNode* pBoxStt =
1795                                     rIdx.GetNode().FindTableBoxStartNode();
1796                 const SwTableBox* pBox = pTblNd->GetTable().GetTblBox(
1797                                                 pBoxStt->GetIndex() );
1798                 const SwTableLine* pLn = pBox->GetUpper();
1799                 pBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
1800                 rIdx = *pBox->GetSttNd()->EndOfSectionNode();
1801                 pPam->Move( fnMoveForward, fnGoNode );
1802             }
1803             nInsTblRow = static_cast< sal_uInt16 >(GetOpenBrakets());
1804             SetPardTokenRead( sal_False );
1805             SwPaM aTmp(*pPam);
1806             aTmp.Move( fnMoveBackward, fnGoNode );
1807         }
1808         ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
1809         break;
1810 
1811     case RTF_INTBL:
1812         if (!CantUseTables())
1813         {
1814             if( !pTableNode )           // Tabelle nicht mehr vorhanden ?
1815             {
1816                 if (RTF_TROWD != GetNextToken())
1817                     NewTblLine();           // evt. Line copieren
1818                 SkipToken(-1);
1819             }
1820             else
1821             {
1822                 // Crsr nicht mehr in der Tabelle ?
1823                 if( !pPam->GetNode()->FindTableNode() )
1824                 {
1825                     // dann wieder in die letzte Box setzen
1826                     // (kann durch einlesen von Flys geschehen!)
1827                     pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
1828                     pPam->Move( fnMoveBackward );
1829                 }
1830             }
1831         }
1832         break;
1833 
1834     case RTF_REVTBL:
1835         ReadRevTbl();
1836         break;
1837 
1838     case RTF_REVISED:
1839         pRedlineInsert = new SwFltRedline(nsRedlineType_t::REDLINE_INSERT, 0, DateTime(Date( 0 ), Time( 0 )));
1840         break;
1841 
1842     case RTF_DELETED:
1843         pRedlineDelete = new SwFltRedline(nsRedlineType_t::REDLINE_DELETE, 0, DateTime(Date( 0 ), Time( 0 )));
1844         break;
1845 
1846     case RTF_REVAUTH:
1847         {
1848             sw::util::AuthorInfo aEntry( static_cast< sal_uInt16 >(nTokenValue) );
1849             sal_uInt16 nPos;
1850 
1851             if(pRedlineInsert)
1852             {
1853                 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
1854                 {
1855                     if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
1856                     {
1857                         pRedlineInsert->nAutorNo = pAuthor->nOurId;
1858                     }
1859                 }
1860             }
1861         }
1862         break;
1863 
1864     case RTF_REVAUTHDEL:
1865         {
1866             sw::util::AuthorInfo aEntry( static_cast< short >(nTokenValue) );
1867             sal_uInt16 nPos;
1868 
1869             if(pRedlineDelete)
1870             {
1871                 if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
1872                 {
1873                     if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
1874                     {
1875                         pRedlineDelete->nAutorNo = pAuthor->nOurId;
1876                     }
1877                 }
1878             }
1879         }
1880         break;
1881 
1882     case RTF_REVDTTM:
1883         if (pRedlineInsert != NULL)
1884             pRedlineInsert->aStamp = sw::ms::DTTM2DateTime(nTokenValue);
1885 
1886         break;
1887 
1888     case RTF_REVDTTMDEL:
1889         pRedlineDelete->aStamp = sw::ms::DTTM2DateTime(nTokenValue);
1890         break;
1891 
1892 
1893     case RTF_FLY_INPARA:
1894             // \pard  und plain ueberlesen !
1895         if( '}' != GetNextToken() && '}' != GetNextToken() )
1896         {
1897             // Zeichengebundener Fly in Fly
1898             ReadHeaderFooter( nToken );
1899             SetPardTokenRead( sal_False );
1900         }
1901         break;
1902 
1903     case RTF_PGDSCNO:
1904         if( IsNewDoc() && bSwPageDesc &&
1905             sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() )
1906         {
1907             const SwPageDesc* pPgDsc =
1908                 &const_cast<const SwDoc *>(pDoc)
1909                 ->GetPageDesc( sal_uInt16(nTokenValue) );
1910             CheckInsNewTblLine();
1911             pDoc->InsertPoolItem(*pPam, SwFmtPageDesc( pPgDsc ), 0);
1912         }
1913         break;
1914 
1915     case RTF_COLUM:
1916         pDoc->InsertPoolItem(*pPam,
1917                 SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0);
1918         break;
1919 
1920     case RTF_DXFRTEXT:      // werden nur im Zusammenhang mit Flys ausgewertet
1921     case RTF_DFRMTXTX:
1922     case RTF_DFRMTXTY:
1923         break;
1924 
1925     case RTF_CHDATE:    eDateFmt = DF_SHORT;    goto SETCHDATEFIELD;
1926     case RTF_CHDATEA:   eDateFmt = DF_SSYS;     goto SETCHDATEFIELD;
1927     case RTF_CHDATEL:   eDateFmt = DF_LSYS;     goto SETCHDATEFIELD;
1928 SETCHDATEFIELD:
1929         {
1930             sal_uInt16 nSubType = DATEFLD, nWhich = RES_DATEFLD;
1931             sal_uLong nFormat = eDateFmt;
1932             sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
1933 
1934             SwDateTimeField aDateFld( (SwDateTimeFieldType*)
1935                                         pDoc->GetSysFldType( RES_DATETIMEFLD ), DATEFLD, nFormat);
1936             CheckInsNewTblLine();
1937             pDoc->InsertPoolItem(*pPam, SwFmtFld( aDateFld ), 0);
1938         }
1939         break;
1940 
1941     case RTF_CHTIME:
1942         {
1943             sal_uInt16 nSubType = TIMEFLD, nWhich = RES_TIMEFLD;
1944             sal_uLong nFormat = TF_SSMM_24;
1945             sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 );
1946             SwDateTimeField aTimeFld( (SwDateTimeFieldType*)
1947                     pDoc->GetSysFldType( RES_DATETIMEFLD ), TIMEFLD, nFormat);
1948             CheckInsNewTblLine();
1949             pDoc->InsertPoolItem(*pPam, SwFmtFld( aTimeFld ), 0);
1950         }
1951         break;
1952 
1953     case RTF_CHPGN:
1954         {
1955             SwPageNumberField aPageFld( (SwPageNumberFieldType*)
1956                                     pDoc->GetSysFldType( RES_PAGENUMBERFLD ),
1957                                     PG_RANDOM, SVX_NUM_ARABIC );
1958             CheckInsNewTblLine();
1959             pDoc->InsertPoolItem(*pPam, SwFmtFld(aPageFld), 0);
1960         }
1961         break;
1962 
1963     case RTF_CHFTN:
1964         bFootnoteAutoNum = sal_True;
1965         break;
1966 
1967     case RTF_NOFPAGES:
1968         if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
1969             ((SwDocStat&)pDoc->GetDocStat()).nPage = (sal_uInt16)nTokenValue;
1970         break;
1971 
1972     case RTF_NOFWORDS:
1973         if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
1974             ((SwDocStat&)pDoc->GetDocStat()).nWord = (sal_uInt16)nTokenValue;
1975         break;
1976     case RTF_NOFCHARS:
1977         if( IsNewDoc() && nTokenValue && -1 != nTokenValue )
1978             ((SwDocStat&)pDoc->GetDocStat()).nChar = (sal_uInt16)nTokenValue;
1979         break;
1980     case RTF_LYTPRTMET:
1981         if (IsNewDoc())
1982             pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, false);
1983         break;
1984     case RTF_U:
1985         {
1986             CheckInsNewTblLine();
1987             if( nTokenValue )
1988                 aToken = (sal_Unicode )nTokenValue;
1989             pDoc->InsertString( *pPam, aToken );
1990         }
1991         break;
1992 
1993     case RTF_USERPROPS:
1994         ReadUserProperties();       // #i28758 For now we don't support user properties
1995         break;
1996 
1997 // RTF_SUBENTRYINDEX
1998 
1999     default:
2000         switch( nToken & ~(0xff | RTF_SWGDEFS) )
2001         {
2002         case RTF_DOCFMT:
2003             ReadDocControls( nToken );
2004             break;
2005         case RTF_SECTFMT:
2006             ReadSectControls( nToken );
2007             break;
2008         case RTF_APOCTL:
2009             if (nReadFlyDepth < 10)
2010             {
2011                 nReadFlyDepth++;
2012                 ReadFly( nToken );
2013                 nReadFlyDepth--;
2014             }
2015             break;
2016 
2017         case RTF_BRDRDEF | RTF_TABLEDEF:
2018         case RTF_SHADINGDEF | RTF_TABLEDEF:
2019         case RTF_TABLEDEF:
2020             ReadTable( nToken );
2021             break;
2022 
2023         case RTF_INFO:
2024             ReadInfo();
2025             break;
2026 
2027         default:
2028             if( USHRT_MAX != nInsTblRow &&
2029                 (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2030                 nInsTblRow = USHRT_MAX;
2031 
2032             SvxRTFParser::NextToken( nToken );
2033             break;
2034         }
2035     }
2036     if( USHRT_MAX != nInsTblRow &&
2037         (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() ))
2038         nInsTblRow = USHRT_MAX;
2039 }
2040 
2041 
2042 
InsertText()2043 void SwRTFParser::InsertText()
2044 {
2045     bContainsPara = false;
2046     // dann fuege den String ein, ohne das Attribute am Ende
2047     // aufgespannt werden.
2048     CheckInsNewTblLine();
2049 
2050     if(pRedlineInsert)
2051         mpRedlineStack->open(*pPam->GetPoint(), *pRedlineInsert);
2052     if(pRedlineDelete)
2053         mpRedlineStack->open(*pPam->GetPoint(), *pRedlineDelete);
2054 
2055     pDoc->InsertString( *pPam, aToken );
2056 
2057     if(pRedlineDelete)
2058     {
2059         mpRedlineStack->close(*pPam->GetPoint(), pRedlineDelete->eType);
2060     }
2061 
2062     if(pRedlineInsert)
2063     {
2064         mpRedlineStack->close(*pPam->GetPoint(), pRedlineInsert->eType);
2065     }
2066 
2067 
2068 }
2069 
2070 
InsertPara()2071 void SwRTFParser::InsertPara()
2072 {
2073     bContainsPara = true;
2074     CheckInsNewTblLine();
2075     pDoc->AppendTxtNode(*pPam->GetPoint());
2076 
2077     // setze das default Style
2078     if( !bStyleTabValid )
2079         MakeStyleTab();
2080 
2081     SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
2082     if( !pColl )
2083         pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
2084     pDoc->SetTxtFmtColl( *pPam, pColl );
2085 
2086     ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() );
2087 }
2088 
2089 
2090 
MovePos(int bForward)2091 void SwRTFParser::MovePos( int bForward )
2092 {
2093     if( bForward )
2094         pPam->Move( fnMoveForward );
2095     else
2096         pPam->Move( fnMoveBackward );
2097 }
2098 
IsEndPara(SvxNodeIdx * pNd,xub_StrLen nCnt) const2099 int SwRTFParser::IsEndPara( SvxNodeIdx* pNd, xub_StrLen nCnt ) const
2100 {
2101     SwCntntNode *pNode = pDoc->GetNodes()[pNd->GetIdx()]->GetCntntNode();
2102     return pNode && pNode->Len() == nCnt;
2103 }
2104 
UncompressableStackEntry(const SvxRTFItemStackType & rSet) const2105 bool SwRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &rSet)
2106     const
2107 {
2108     /*
2109     #i21961#
2110     Seeing as CHARFMT sets all the properties of the charfmt itself, its not
2111     good enough to just see it as a single property from the point of
2112     compressing property sets. If bold and charfmt are in a child, and bold is
2113     in the parent, removing bold from the child will not result in the same
2114     thing, if the charfmt removes bold itself for example
2115     */
2116     bool bRet = false;
2117     if (rSet.GetAttrSet().Count())
2118     {
2119 
2120         if (SFX_ITEM_SET ==
2121                 rSet.GetAttrSet().GetItemState(RES_TXTATR_CHARFMT, sal_False))
2122         {
2123             bRet = true;
2124         }
2125     }
2126     return bRet;
2127 }
2128 
SetEndPrevPara(SvxNodeIdx * & rpNodePos,xub_StrLen & rCntPos)2129 void SwRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos, xub_StrLen& rCntPos )
2130 {
2131     SwNodeIndex aIdx( pPam->GetPoint()->nNode );
2132     SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aIdx );
2133     if( !pNode )
2134     {
2135         ASSERT( sal_False, "keinen vorherigen ContentNode gefunden" );
2136     }
2137 
2138     rpNodePos = new SwNodeIdx( aIdx );
2139     rCntPos = pNode->Len();
2140 }
2141 
SetAttrInDoc(SvxRTFItemStackType & rSet)2142 void SwRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet )
2143 {
2144     sal_uLong nSNd = rSet.GetSttNodeIdx(), nENd = rSet.GetEndNodeIdx();
2145     xub_StrLen nSCnt = rSet.GetSttCnt(), nECnt = rSet.GetEndCnt();
2146 
2147     SwPaM aPam( *pPam->GetPoint() );
2148 
2149 #ifdef DBG_UTIL
2150     ASSERT( nSNd <= nENd, "Start groesser als Ende" );
2151     SwNode* pDebugNd = pDoc->GetNodes()[ nSNd ];
2152     ASSERT( pDebugNd->IsCntntNode(), "Start kein ContentNode" );
2153     pDebugNd = pDoc->GetNodes()[ nENd ];
2154     ASSERT( pDebugNd->IsCntntNode(), "Ende kein ContentNode" );
2155 #endif
2156 
2157     SwCntntNode* pCNd = pDoc->GetNodes()[ nSNd ]->GetCntntNode();
2158     aPam.GetPoint()->nNode = nSNd;
2159     aPam.GetPoint()->nContent.Assign( pCNd, nSCnt );
2160     aPam.SetMark();
2161     if( nENd == nSNd )
2162         aPam.GetPoint()->nContent = nECnt;
2163     else
2164     {
2165         aPam.GetPoint()->nNode = nENd;
2166         pCNd = aPam.GetCntntNode();
2167         aPam.GetPoint()->nContent.Assign( pCNd, nECnt );
2168     }
2169 
2170     // setze ueber den Bereich das entsprechende Style
2171     if( rSet.StyleNo() )
2172     {
2173         // setze jetzt das Style
2174         if( !bStyleTabValid )
2175             MakeStyleTab();
2176         SwTxtFmtColl* pColl = aTxtCollTbl.Get( rSet.StyleNo() );
2177         if( pColl )
2178             pDoc->SetTxtFmtColl( aPam, pColl, false );
2179     }
2180 
2181     const SfxPoolItem* pItem;
2182     const SfxPoolItem* pCharFmt;
2183     if (rSet.GetAttrSet().Count() )
2184     {
2185 
2186         // falls eine Zeichenvorlage im Set steht, deren Attribute
2187         // aus dem Set loeschen. Sonst sind diese doppelt, was man ja
2188         // nicht will.
2189         if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2190             RES_TXTATR_CHARFMT, sal_False, &pCharFmt ) &&
2191             ((SwFmtCharFmt*)pCharFmt)->GetCharFmt() )
2192         {
2193             const String& rName = ((SwFmtCharFmt*)pCharFmt)->GetCharFmt()->GetName();
2194             SvxRTFStyleType* pStyle = GetStyleTbl().First();
2195             do {
2196                 if( pStyle->bIsCharFmt && pStyle->sName == rName )
2197                 {
2198                     // alle Attribute, die schon vom Style definiert sind, aus dem
2199                     // akt. AttrSet entfernen
2200                     SfxItemSet &rAttrSet = rSet.GetAttrSet(),
2201                                &rStyleSet = pStyle->aAttrSet;
2202                     SfxItemIter aIter( rAttrSet );
2203                     sal_uInt16 nWhich = aIter.GetCurItem()->Which();
2204                     while( sal_True )
2205                     {
2206                         const SfxPoolItem* pI;
2207                         if( SFX_ITEM_SET == rStyleSet.GetItemState(
2208                             nWhich, sal_False, &pI ) && *pI == *aIter.GetCurItem())
2209                             rAttrSet.ClearItem( nWhich );       // loeschen
2210 
2211                         if( aIter.IsAtEnd() )
2212                             break;
2213                         nWhich = aIter.NextItem()->Which();
2214                     }
2215                     break;
2216                 }
2217             } while( 0 != (pStyle = GetStyleTbl().Next()) );
2218 
2219             pDoc->InsertPoolItem(aPam, *pCharFmt, 0);
2220             rSet.GetAttrSet().ClearItem(RES_TXTATR_CHARFMT);     //test hack
2221         }
2222         if (rSet.GetAttrSet().Count())
2223         {
2224             // dann setze ueber diesen Bereich die Attrbiute
2225             SetSwgValues(rSet.GetAttrSet());
2226             pDoc->InsertItemSet(aPam, rSet.GetAttrSet(),
2227                     nsSetAttrMode::SETATTR_DONTCHGNUMRULE);
2228         }
2229     }
2230 
2231     if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2232         FN_PARAM_NUM_LEVEL, sal_False, &pItem ))
2233     {
2234         // dann ueber den Bereich an den Nodes das NodeNum setzen
2235         for( sal_uLong n = nSNd; n <= nENd; ++n )
2236         {
2237             SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2238             if( pTxtNd )
2239             {
2240                 pTxtNd->SetAttrListLevel((sal_uInt8) ((SfxUInt16Item*)pItem)->GetValue());
2241                 // Update vom LR-Space abschalten?
2242             }
2243         }
2244     }
2245 
2246     if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(
2247         RES_PARATR_NUMRULE, sal_False, &pItem ))
2248     {
2249         const SwNumRule* pRule = pDoc->FindNumRulePtr(
2250                                     ((SwNumRuleItem*)pItem)->GetValue() );
2251         if( pRule && ( pRule->IsContinusNum() || !bNewNumList ))
2252         {
2253             // diese Rule hat keinen Level, also muss die Einrueckung
2254             // erhalten bleiben!
2255             // dann ueber den Bereich an den Nodes das Flag zuruecksetzen
2256             for( sal_uLong n = nSNd; n <= nENd; ++n )
2257             {
2258                 SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2259                 if( pTxtNd )
2260                 {
2261                     // Update vom LR-Space abschalten
2262                     pTxtNd->SetNumLSpace( sal_False );
2263                 }
2264             }
2265         }
2266     }
2267 
2268     bool bNoNum = true;
2269     if (
2270         (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(RES_PARATR_NUMRULE))
2271      || (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(FN_PARAM_NUM_LEVEL))
2272        )
2273     {
2274         bNoNum = false;
2275     }
2276 
2277     if (bNoNum)
2278     {
2279         for( sal_uLong n = nSNd; n <= nENd; ++n )
2280         {
2281             SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode();
2282             if( pTxtNd )
2283             {
2284                 pTxtNd->SetAttr( *GetDfltAttr(RES_PARATR_NUMRULE) );
2285                 // reset all list attributes
2286                 pTxtNd->ResetAttr( RES_PARATR_LIST_LEVEL );
2287                 pTxtNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
2288                 pTxtNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
2289                 pTxtNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
2290                 pTxtNd->ResetAttr( RES_PARATR_LIST_ID );
2291             }
2292         }
2293     }
2294 }
2295 
DocPageInformation()2296 DocPageInformation::DocPageInformation()
2297     : maBox( RES_BOX ),
2298     mnPaperw(12240), mnPaperh(15840), mnMargl(1800), mnMargr(1800),
2299     mnMargt(1440), mnMargb(1440), mnGutter(0), mnPgnStart(1), mbFacingp(false),
2300     mbLandscape(false), mbRTLdoc(false)
2301 {
2302 }
2303 
SectPageInformation(const DocPageInformation & rDoc)2304 SectPageInformation::SectPageInformation(const DocPageInformation &rDoc)
2305     : maBox(rDoc.maBox), mpTitlePageHdFt(0), mpPageHdFt(0),
2306     mnPgwsxn(rDoc.mnPaperw), mnPghsxn(rDoc.mnPaperh), mnMarglsxn(rDoc.mnMargl),
2307     mnMargrsxn(rDoc.mnMargr), mnMargtsxn(rDoc.mnMargt),
2308     mnMargbsxn(rDoc.mnMargb), mnGutterxsn(rDoc.mnGutter), mnHeadery(720),
2309     mnFootery(720), mnPgnStarts(rDoc.mnPgnStart), mnCols(1), mnColsx(720),
2310     mnStextflow(rDoc.mbRTLdoc ? 3 : 0), mnBkc(2), mbLndscpsxn(rDoc.mbLandscape),
2311     mbTitlepg(false), mbFacpgsxn(rDoc.mbFacingp), mbRTLsection(rDoc.mbRTLdoc),
2312     mbPgnrestart(false), mbTitlePageHdFtUsed(false), mbPageHdFtUsed(false)
2313 {
2314 };
2315 
SectPageInformation(const SectPageInformation & rSect)2316 SectPageInformation::SectPageInformation(const SectPageInformation &rSect)
2317     : maColumns(rSect.maColumns), maBox(rSect.maBox),
2318     maNumType(rSect.maNumType), mpTitlePageHdFt(rSect.mpTitlePageHdFt),
2319     mpPageHdFt(rSect.mpPageHdFt), mnPgwsxn(rSect.mnPgwsxn),
2320     mnPghsxn(rSect.mnPghsxn), mnMarglsxn(rSect.mnMarglsxn),
2321     mnMargrsxn(rSect.mnMargrsxn), mnMargtsxn(rSect.mnMargtsxn),
2322     mnMargbsxn(rSect.mnMargbsxn), mnGutterxsn(rSect.mnGutterxsn),
2323     mnHeadery(rSect.mnHeadery), mnFootery(rSect.mnFootery),
2324     mnPgnStarts(rSect.mnPgnStarts), mnCols(rSect.mnCols),
2325     mnColsx(rSect.mnColsx), mnStextflow(rSect.mnStextflow), mnBkc(rSect.mnBkc),
2326     mbLndscpsxn(rSect.mbLndscpsxn), mbTitlepg(rSect.mbTitlepg),
2327     mbFacpgsxn(rSect.mbFacpgsxn), mbRTLsection(rSect.mbRTLsection),
2328     mbPgnrestart(rSect.mbPgnrestart),
2329     mbTitlePageHdFtUsed(rSect.mbTitlePageHdFtUsed),
2330     mbPageHdFtUsed(rSect.mbPageHdFtUsed)
2331 {
2332 };
2333 
rtfSection(const SwPosition & rPos,const SectPageInformation & rPageInfo)2334 rtfSection::rtfSection(const SwPosition &rPos,
2335     const SectPageInformation &rPageInfo)
2336     : maStart(rPos.nNode), maPageInfo(rPageInfo), mpSection(0), mpTitlePage(0),
2337     mpPage(0)
2338 {
2339 }
2340 
push_back(const rtfSection & rSect)2341 void rtfSections::push_back(const rtfSection &rSect)
2342 {
2343     if (!maSegments.empty() && (maSegments.back().maStart == rSect.maStart))
2344         maSegments.pop_back();
2345     maSegments.push_back(rSect);
2346 }
2347 
2348 // lese alle Dokument-Controls ein
SetPageInformationAsDefault(const DocPageInformation & rInfo)2349 void SwRTFParser::SetPageInformationAsDefault(const DocPageInformation &rInfo)
2350 {
2351     //If we are at the beginning of the document then start the document with
2352     //a segment with these properties. See #i14982# for this requirement
2353     rtfSection aSect(*pPam->GetPoint(), SectPageInformation(rInfo));
2354     if (maSegments.empty() || (maSegments.back().maStart == aSect.maStart))
2355         maSegments.push_back(aSect);
2356 
2357     if (!bSwPageDesc && IsNewDoc())
2358     {
2359         SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, rInfo.mnPaperw, rInfo.mnPaperh);
2360 
2361         SvxLRSpaceItem aLR( static_cast< sal_uInt16 >(rInfo.mnMargl), static_cast< sal_uInt16 >(rInfo.mnMargr), 0, 0, RES_LR_SPACE );
2362         SvxULSpaceItem aUL( static_cast< sal_uInt16 >(rInfo.mnMargt), static_cast< sal_uInt16 >(rInfo.mnMargb), RES_UL_SPACE );
2363 
2364         UseOnPage eUseOn;
2365         if (rInfo.mbFacingp)
2366             eUseOn = UseOnPage(nsUseOnPage::PD_MIRROR | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2367         else
2368             eUseOn = UseOnPage(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
2369 
2370         sal_uInt16 nPgStart = static_cast< sal_uInt16 >(rInfo.mnPgnStart);
2371 
2372         SvxFrameDirectionItem aFrmDir(rInfo.mbRTLdoc ?
2373             FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
2374 
2375         // direkt an der Standartseite drehen
2376         SwPageDesc& rPg = pDoc->_GetPageDesc( 0 );
2377         rPg.WriteUseOn( eUseOn );
2378 
2379         if (rInfo.mbLandscape)
2380             rPg.SetLandscape(true);
2381 
2382         SwFrmFmt &rFmt1 = rPg.GetMaster(), &rFmt2 = rPg.GetLeft();
2383 
2384         rFmt1.SetFmtAttr( aFrmSize );   rFmt2.SetFmtAttr( aFrmSize );
2385         rFmt1.SetFmtAttr( aLR );        rFmt2.SetFmtAttr( aLR );
2386         rFmt1.SetFmtAttr( aUL );       rFmt2.SetFmtAttr( aUL );
2387         rFmt1.SetFmtAttr( aFrmDir );   rFmt2.SetFmtAttr( aFrmDir );
2388 
2389         // StartNummer der Seiten setzen
2390         if (nPgStart  != 1)
2391         {
2392             SwFmtPageDesc aPgDsc( &rPg );
2393             aPgDsc.SetNumOffset( nPgStart );
2394             pDoc->InsertPoolItem( *pPam, aPgDsc, 0 );
2395         }
2396     }
2397 }
2398 
SetBorderLine(SvxBoxItem & rBox,sal_uInt16 nLine)2399 void SwRTFParser::SetBorderLine(SvxBoxItem& rBox, sal_uInt16 nLine)
2400 {
2401     int bWeiter = true;
2402     short nLineThickness = 1;
2403     short nPageDistance = 0;
2404     sal_uInt8 nCol = 0;
2405     short nIdx = 0;
2406 
2407     int nToken = GetNextToken();
2408     do {
2409         switch( nToken )
2410         {
2411         case RTF_BRDRS:
2412             nIdx = 1;
2413             break;
2414 
2415         case RTF_BRDRDB:
2416             nIdx = 3;
2417             break;
2418 
2419         case RTF_BRDRTRIPLE:
2420             nIdx = 10;
2421             break;
2422 
2423         case RTF_BRDRTNTHSG:
2424             nIdx = 11;
2425             break;
2426 
2427         case RTF_BRDRTHTNSG:
2428             nIdx = 12;
2429             break;
2430 
2431         case RTF_BRDRTNTHTNSG:
2432             nIdx = 13;
2433             break;
2434 
2435         case RTF_BRDRTNTHMG:
2436             nIdx = 14;
2437             break;
2438 
2439         case RTF_BRDRTHTNMG:
2440             nIdx = 15;
2441             break;
2442 
2443         case RTF_BRDRTNTHTNMG:
2444             nIdx = 16;
2445             break;
2446 
2447         case RTF_BRDRTNTHLG:
2448             nIdx = 17;
2449             break;
2450 
2451         case RTF_BRDRTHTNLG:
2452             nIdx = 18;
2453             break;
2454 
2455         case RTF_BRDRTNTHTNLG:
2456             nIdx = 19;
2457             break;
2458 
2459         case RTF_BRDRWAVY:
2460             nIdx = 20;
2461             break;
2462 
2463         case RTF_BRDRWAVYDB:
2464             nIdx = 21;
2465             break;
2466 
2467         case RTF_BRDREMBOSS:
2468             nIdx = 24;
2469             break;
2470 
2471         case RTF_BRDRENGRAVE:
2472             nIdx = 25;
2473             break;
2474 
2475         case RTF_BRSP:
2476             nPageDistance = static_cast< short >(nTokenValue);
2477             break;
2478 
2479         case RTF_BRDRDOT:           // SO does not have dashed or dotted lines
2480         case RTF_BRDRDASH:
2481         case RTF_BRDRDASHSM:
2482         case RTF_BRDRDASHD:
2483         case RTF_BRDRDASHDD:
2484         case RTF_BRDRDASHDOTSTR:
2485         case RTF_BRDRSH:            // shading not supported
2486         case RTF_BRDRCF:            // colors not supported
2487             break;
2488 
2489         case RTF_BRDRW:
2490             nLineThickness = static_cast< short >(nTokenValue);
2491             break;
2492         default:
2493             bWeiter = false;
2494             SkipToken(-1);
2495             break;
2496         }
2497         if (bWeiter)
2498             nToken = GetNextToken();
2499     } while (bWeiter && IsParserWorking());
2500 
2501     GetLineIndex(rBox, nLineThickness, nPageDistance, nCol, nIdx, nLine, nLine, 0);
2502 }
2503 
2504 // lese alle Dokument-Controls ein
ReadDocControls(int nToken)2505 void SwRTFParser::ReadDocControls( int nToken )
2506 {
2507     int bWeiter = true;
2508 
2509     SwFtnInfo aFtnInfo;
2510     SwEndNoteInfo aEndInfo;
2511     bool bSetHyph = false;
2512 
2513     sal_Bool bEndInfoChgd = sal_False, bFtnInfoChgd = sal_False;
2514 
2515     do {
2516         sal_uInt16 nValue = sal_uInt16( nTokenValue );
2517         switch( nToken )
2518         {
2519         case RTF_RTLDOC:
2520             maPageDefaults.mbRTLdoc = true;
2521             break;
2522         case RTF_LTRDOC:
2523             maPageDefaults.mbRTLdoc = false;
2524             break;
2525         case RTF_LANDSCAPE:
2526             maPageDefaults.mbLandscape = true;
2527             break;
2528         case RTF_PAPERW:
2529             if( 0 < nTokenValue )
2530                 maPageDefaults.mnPaperw = nTokenValue;
2531             break;
2532         case RTF_PAPERH:
2533             if( 0 < nTokenValue )
2534                 maPageDefaults.mnPaperh = nTokenValue;
2535             break;
2536         case RTF_MARGL:
2537             if( 0 <= nTokenValue )
2538                 maPageDefaults.mnMargl = nTokenValue;
2539             break;
2540         case RTF_MARGR:
2541             if( 0 <= nTokenValue )
2542                 maPageDefaults.mnMargr = nTokenValue;
2543             break;
2544         case RTF_MARGT:
2545             if( 0 <= nTokenValue )
2546                 maPageDefaults.mnMargt = nTokenValue;
2547             break;
2548         case RTF_MARGB:
2549             if( 0 <= nTokenValue )
2550                 maPageDefaults.mnMargb = nTokenValue;
2551             break;
2552         case RTF_FACINGP:
2553             maPageDefaults.mbFacingp = true;
2554             break;
2555         case RTF_PGNSTART:
2556             maPageDefaults.mnPgnStart = nTokenValue;
2557             break;
2558         case RTF_ENDDOC:
2559         case RTF_ENDNOTES:
2560             aFtnInfo.ePos = FTNPOS_CHAPTER; bFtnInfoChgd = sal_True;
2561             break;
2562         case RTF_FTNTJ:
2563         case RTF_FTNBJ:
2564             aFtnInfo.ePos = FTNPOS_PAGE; bFtnInfoChgd = sal_True;
2565             break;
2566 
2567         case RTF_AENDDOC:
2568         case RTF_AENDNOTES:
2569         case RTF_AFTNTJ:
2570         case RTF_AFTNBJ:
2571         case RTF_AFTNRESTART:
2572         case RTF_AFTNRSTCONT:
2573             break;      // wir kenn nur am Doc Ende und Doc weite Num.!
2574 
2575         case RTF_FTNSTART:
2576             if( nValue )
2577             {
2578                 aFtnInfo.nFtnOffset = nValue-1;
2579                 bFtnInfoChgd = sal_True;
2580             }
2581             break;
2582         case RTF_AFTNSTART:
2583             if( nValue )
2584             {
2585                 aEndInfo.nFtnOffset = nValue-1;
2586                 bEndInfoChgd = sal_True;
2587             }
2588             break;
2589         case RTF_FTNRSTPG:
2590             aFtnInfo.eNum = FTNNUM_PAGE; bFtnInfoChgd = sal_True;
2591             break;
2592         case RTF_FTNRESTART:
2593             aFtnInfo.eNum = FTNNUM_CHAPTER; bFtnInfoChgd = sal_True;
2594             break;
2595         case RTF_FTNRSTCONT:
2596             aFtnInfo.eNum = FTNNUM_DOC; bFtnInfoChgd = sal_True;
2597             break;
2598 
2599         case RTF_FTNNAR:
2600             aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bFtnInfoChgd = sal_True; break;
2601         case RTF_FTNNALC:
2602             aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); bFtnInfoChgd = sal_True; break;
2603         case RTF_FTNNAUC:
2604             aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); bFtnInfoChgd = sal_True; break;
2605         case RTF_FTNNRLC:
2606             aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); bFtnInfoChgd = sal_True; break;
2607         case RTF_FTNNRUC:
2608             aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); bFtnInfoChgd = sal_True; break;
2609         case RTF_FTNNCHI:
2610             aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); bFtnInfoChgd = sal_True; break;
2611 
2612         case RTF_AFTNNAR:
2613             aEndInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bEndInfoChgd = sal_True; break;
2614         case RTF_AFTNNALC:
2615             aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N);
2616             bEndInfoChgd = sal_True;
2617             break;
2618         case RTF_AFTNNAUC:
2619             aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N);
2620             bEndInfoChgd = sal_True;
2621             break;
2622         case RTF_AFTNNRLC:
2623             aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);
2624             bEndInfoChgd = sal_True;
2625             break;
2626         case RTF_AFTNNRUC:
2627             aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2628             bEndInfoChgd = sal_True;
2629             break;
2630         case RTF_AFTNNCHI:
2631             aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
2632             bEndInfoChgd = sal_True;
2633             break;
2634         case RTF_HYPHAUTO:
2635             if (nTokenValue)
2636                 bSetHyph = true;
2637             //FOO//
2638             break;
2639         case RTF_PGBRDRT:
2640             SetBorderLine(maPageDefaults.maBox, BOX_LINE_TOP);
2641             break;
2642 
2643         case RTF_PGBRDRB:
2644             SetBorderLine(maPageDefaults.maBox, BOX_LINE_BOTTOM);
2645             break;
2646 
2647         case RTF_PGBRDRL:
2648             SetBorderLine(maPageDefaults.maBox, BOX_LINE_LEFT);
2649             break;
2650 
2651         case RTF_PGBRDRR:
2652             SetBorderLine(maPageDefaults.maBox, BOX_LINE_RIGHT);
2653             break;
2654 
2655         case '{':
2656             {
2657                 short nSkip = 0;
2658                 if( RTF_IGNOREFLAG != GetNextToken() )
2659                     nSkip = -1;
2660                 else if( RTF_DOCFMT != (( nToken = GetNextToken() )
2661                         & ~(0xff | RTF_SWGDEFS)) )
2662                     nSkip = -2;
2663                 else
2664                 {
2665                     SkipGroup();        // erstmal komplett ueberlesen
2666                     // ueberlese noch die schliessende Klammer
2667                     GetNextToken();
2668                 }
2669                 if( nSkip )
2670                 {
2671                     SkipToken( nSkip );     // Ignore wieder zurueck
2672                     bWeiter = sal_False;
2673                 }
2674             }
2675             break;
2676 
2677         default:
2678             if( RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2679                 RTF_UNKNOWNCONTROL == nToken )
2680                 SvxRTFParser::NextToken( nToken );
2681             else
2682                 bWeiter = sal_False;
2683             break;
2684         }
2685         if( bWeiter )
2686             nToken = GetNextToken();
2687     } while( bWeiter && IsParserWorking() );
2688 
2689     if (IsNewDoc())
2690     {
2691         if( bEndInfoChgd )
2692             pDoc->SetEndNoteInfo( aEndInfo );
2693         if( bFtnInfoChgd )
2694             pDoc->SetFtnInfo( aFtnInfo );
2695     }
2696 
2697     if (!bSwPageDesc)
2698     {
2699         SetPageInformationAsDefault(maPageDefaults);
2700 
2701         MakeStyleTab();
2702 
2703         SwTxtFmtColl* pColl = aTxtCollTbl.Get(0);
2704         if (!pColl)
2705         {
2706             pColl = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
2707         }
2708 
2709         ASSERT(pColl, "impossible to have no standard style");
2710 
2711         if (pColl)
2712         {
2713             if (
2714                 IsNewDoc() && bSetHyph &&
2715                 SFX_ITEM_SET != pColl->GetItemState(RES_PARATR_HYPHENZONE,
2716                 false)
2717                )
2718             {
2719                 pColl->SetFmtAttr(SvxHyphenZoneItem(true, RES_PARATR_HYPHENZONE));
2720             }
2721 
2722             pDoc->SetTxtFmtColl( *pPam, pColl );
2723         }
2724     }
2725 
2726     SkipToken( -1 );
2727 }
2728 
MakeStyleTab()2729 void SwRTFParser::MakeStyleTab()
2730 {
2731 	// dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections
2732 	if( GetStyleTbl().Count() )
2733 	{
2734 		sal_uInt16 nValidOutlineLevels = 0;
2735 		if( !IsNewDoc() )
2736 		{
2737 			// search all outlined collections
2738 			//sal_uInt8 nLvl;
2739 			const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls();
2740 			for( sal_uInt16 n = rColls.Count(); n; )
2741 				//if( MAXLEVEL > (nLvl = rColls[ --n ]->GetOutlineLevel() ))//#outline level,zhaojianwei
2742 				//	nValidOutlineLevels |= 1 << nLvl;
2743 				if( rColls[ --n ]->IsAssignedToListLevelOfOutlineStyle())
2744 					nValidOutlineLevels |= 1 << rColls[ n ]->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei
2745 		}
2746 
2747 		SvxRTFStyleType* pStyle = GetStyleTbl().First();
2748 		do {
2749 			sal_uInt16 nNo = sal_uInt16( GetStyleTbl().GetCurKey() );
2750 			if( pStyle->bIsCharFmt )
2751 			{
2752 				if( !aCharFmtTbl.Get( nNo ) )
2753 					// existiert noch nicht, also anlegen
2754 					MakeCharStyle( nNo, *pStyle );
2755 			}
2756 			else if( !aTxtCollTbl.Get( nNo ) )
2757 			{
2758 				// existiert noch nicht, also anlegen
2759 				MakeStyle( nNo, *pStyle );
2760 			}
2761 
2762 		} while( 0 != (pStyle = GetStyleTbl().Next()) );
2763 		bStyleTabValid = sal_True;
2764 	}
2765 }
2766 
lcl_SetFmtCol(SwFmt & rFmt,sal_uInt16 nCols,sal_uInt16 nColSpace,const SvUShorts & rColumns)2767 sal_Bool lcl_SetFmtCol( SwFmt& rFmt, sal_uInt16 nCols, sal_uInt16 nColSpace,
2768                     const SvUShorts& rColumns )
2769 {
2770     sal_Bool bSet = sal_False;
2771     if( nCols && USHRT_MAX != nCols )
2772     {
2773         SwFmtCol aCol;
2774         if( USHRT_MAX == nColSpace )
2775             nColSpace = 720;
2776 
2777         aCol.Init( nCols, nColSpace, USHRT_MAX );
2778         if( nCols == ( rColumns.Count() / 2 ) )
2779         {
2780             aCol._SetOrtho( sal_False );
2781             sal_uInt16 nWishWidth = 0, nHalfPrev = 0;
2782             for (sal_uInt16 n = 0, i = 0; (n+1) < rColumns.Count(); n += 2, ++i)
2783             {
2784                 SwColumn* pCol = aCol.GetColumns()[ i ];
2785                 pCol->SetLeft( nHalfPrev );
2786                 sal_uInt16 nSp = rColumns[ n+1 ];
2787                 nHalfPrev = nSp / 2;
2788                 pCol->SetRight( nSp - nHalfPrev );
2789                 pCol->SetWishWidth( rColumns[ n ] +
2790                                     pCol->GetLeft() + pCol->GetRight() );
2791                 nWishWidth = nWishWidth + pCol->GetWishWidth();
2792             }
2793             aCol.SetWishWidth( nWishWidth );
2794         }
2795         rFmt.SetFmtAttr( aCol );
2796         bSet = sal_True;
2797     }
2798     return bSet;
2799 }
2800 
DoHairyWriterPageDesc(int nToken)2801 void SwRTFParser::DoHairyWriterPageDesc(int nToken)
2802 {
2803     int bWeiter = sal_True;
2804     do {
2805         if( '{' == nToken )
2806         {
2807             switch( nToken = GetNextToken() )
2808             {
2809             case RTF_IGNOREFLAG:
2810                 if( RTF_SECTFMT != (( nToken = GetNextToken() )
2811                     & ~(0xff | RTF_SWGDEFS)) )
2812                 {
2813                     SkipToken( -2 );    // Ignore und Token wieder zurueck
2814                     bWeiter = sal_False;
2815                     break;
2816                 }
2817                 // kein break, Gruppe ueberspringen
2818 
2819             case RTF_FOOTER:
2820             case RTF_HEADER:
2821             case RTF_FOOTERR:
2822             case RTF_HEADERR:
2823             case RTF_FOOTERL:
2824             case RTF_HEADERL:
2825             case RTF_FOOTERF:
2826             case RTF_HEADERF:
2827                 SkipGroup();        // erstmal komplett ueberlesen
2828                 // ueberlese noch die schliessende Klammer
2829                 GetNextToken();
2830                 break;
2831 
2832             default:
2833                 SkipToken( -1 );            // Ignore wieder zurueck
2834                 bWeiter = sal_False;
2835                 break;
2836             }
2837         }
2838         else if( RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
2839             RTF_UNKNOWNCONTROL == nToken )
2840             SvxRTFParser::NextToken( nToken );
2841         else
2842             bWeiter = sal_False;
2843         if( bWeiter )
2844             nToken = GetNextToken();
2845     } while( bWeiter && IsParserWorking() );
2846     SkipToken( -1 );                    // letztes Token wieder zurueck
2847     return;
2848 }
2849 
ReadSectControls(int nToken)2850 void SwRTFParser::ReadSectControls( int nToken )
2851 {
2852     //this is some hairy stuff to try and retain writer style page descriptors
2853     //in rtf, almost certainy a bad idea, but we've inherited it, so here it
2854     //stays
2855     if (bInPgDscTbl)
2856     {
2857         DoHairyWriterPageDesc(nToken);
2858         return;
2859     }
2860 
2861     ASSERT(!maSegments.empty(), "suspicious to have a section with no "
2862         "page info, though probably legal");
2863     if (maSegments.empty())
2864     {
2865         maSegments.push_back(rtfSection(*pPam->GetPoint(),
2866             SectPageInformation(maPageDefaults)));
2867     }
2868 
2869     SectPageInformation aNewSection(maSegments.back().maPageInfo);
2870 
2871     bool bNewSection = false;
2872     bool bNewSectionHeader = false;
2873     const SwFmtHeader* _pKeepHeader = NULL;
2874     const SwFmtFooter* _pKeepFooter = NULL;
2875     int bWeiter = true;
2876     bool bKeepFooter = false;
2877     do {
2878         sal_uInt16 nValue = sal_uInt16( nTokenValue );
2879         switch( nToken )
2880         {
2881             case RTF_SECT:
2882                 bNewSection = true;
2883                 bForceNewTable = true; // #117882#
2884                 break;
2885             case RTF_SECTD: {
2886                 //Reset to page defaults
2887                 SwPageDesc* oldPageDesc=aNewSection.mpPageHdFt;
2888                 aNewSection = SectPageInformation(maPageDefaults);
2889                 aNewSection.mpPageHdFt=oldPageDesc;
2890                 _pKeepHeader = NULL;
2891                 _pKeepFooter = NULL;
2892                 } break;
2893             case RTF_PGWSXN:
2894                 if (0 < nTokenValue)
2895                     aNewSection.mnPgwsxn = nTokenValue;
2896                 break;
2897             case RTF_PGHSXN:
2898                 if (0 < nTokenValue)
2899                     aNewSection.mnPghsxn = nTokenValue;
2900                 break;
2901             case RTF_MARGLSXN:
2902                 if (0 <= nTokenValue)
2903                     aNewSection.mnMarglsxn = nTokenValue;
2904                 break;
2905             case RTF_MARGRSXN:
2906                 if (0 <= nTokenValue)
2907                     aNewSection.mnMargrsxn = nTokenValue;
2908                 break;
2909             case RTF_MARGTSXN:
2910                 if (0 <= nTokenValue)
2911                     aNewSection.mnMargtsxn = nTokenValue;
2912                 break;
2913             case RTF_MARGBSXN:
2914                 if (0 <= nTokenValue)
2915                     aNewSection.mnMargbsxn = nTokenValue;
2916                 break;
2917             case RTF_FACPGSXN:
2918                 aNewSection.mbFacpgsxn = true;
2919                 break;
2920             case RTF_HEADERY:
2921                 aNewSection.mnHeadery = nTokenValue;
2922                 break;
2923             case RTF_FOOTERY:
2924                 aNewSection.mnFootery = nTokenValue;
2925                 break;
2926             case RTF_LNDSCPSXN:
2927                 aNewSection.mbLndscpsxn = true;
2928                 break;
2929             case RTF_PGNSTARTS:
2930                 aNewSection.mnPgnStarts = nTokenValue;
2931                 break;
2932             case RTF_PGNDEC:
2933                 aNewSection.maNumType.SetNumberingType(SVX_NUM_ARABIC);
2934                 break;
2935             case RTF_PGNUCRM:
2936                 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_UPPER);
2937                 break;
2938             case RTF_PGNLCRM:
2939                 aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_LOWER);
2940                 break;
2941             case RTF_PGNUCLTR:
2942                 aNewSection.maNumType.SetNumberingType(
2943                     SVX_NUM_CHARS_UPPER_LETTER_N);
2944                 break;
2945             case RTF_PGNLCLTR:
2946                 aNewSection.maNumType.SetNumberingType(
2947                     SVX_NUM_CHARS_LOWER_LETTER_N);
2948                 break;
2949             case RTF_SBKNONE:
2950                 aNewSection.mnBkc = 0;
2951                 break;
2952             case RTF_SBKCOL:
2953                 aNewSection.mnBkc = 1;
2954                 break;
2955             case RTF_PGBRDRT:
2956                 SetBorderLine(aNewSection.maBox, BOX_LINE_TOP);
2957                 break;
2958 
2959             case RTF_PGBRDRB:
2960                 SetBorderLine(aNewSection.maBox, BOX_LINE_BOTTOM);
2961                 break;
2962 
2963             case RTF_PGBRDRL:
2964                 SetBorderLine(aNewSection.maBox, BOX_LINE_LEFT);
2965                 break;
2966 
2967             case RTF_PGBRDRR:
2968                 SetBorderLine(aNewSection.maBox, BOX_LINE_RIGHT);
2969                 break;
2970 
2971             case RTF_PGBRDROPT:
2972             case RTF_ENDNHERE:
2973             case RTF_BINFSXN:
2974             case RTF_BINSXN:
2975             case RTF_SBKPAGE:
2976             case RTF_SBKEVEN:
2977             case RTF_SBKODD:
2978             case RTF_LINEBETCOL:
2979             case RTF_LINEMOD:
2980             case RTF_LINEX:
2981             case RTF_LINESTARTS:
2982             case RTF_LINERESTART:
2983             case RTF_LINEPAGE:
2984             case RTF_LINECONT:
2985             case RTF_GUTTERSXN:
2986             case RTF_PGNCONT:
2987             case RTF_PGNRESTART:
2988             case RTF_PGNX:
2989             case RTF_PGNY:
2990             case RTF_VERTALT:
2991             case RTF_VERTALB:
2992             case RTF_VERTALC:
2993             case RTF_VERTALJ:
2994                 break;
2995             case RTF_TITLEPG:
2996                 aNewSection.mbTitlepg = true;
2997                 break;
2998             case RTF_HEADER:
2999             case RTF_HEADERL:
3000             case RTF_HEADERR:
3001                 if (aNewSection.mpPageHdFt!=NULL)
3002                 {
3003                     _pKeepHeader = NULL;
3004                     bKeepFooter = true; // #i82008
3005                     _pKeepFooter = &aNewSection.mpPageHdFt->GetMaster().GetFooter();
3006                 }
3007             case RTF_FOOTER:
3008             case RTF_FOOTERL:
3009             case RTF_FOOTERR:
3010                 if (aNewSection.mpPageHdFt!=NULL && !bKeepFooter )
3011                 {
3012                     _pKeepFooter = NULL;
3013                     _pKeepHeader = &aNewSection.mpPageHdFt->GetMaster().GetHeader();
3014                 }
3015                 bKeepFooter = false;
3016                 if (!bNewSectionHeader) { //see #117914# topic 2). If a header is redefined in a section
3017                     bNewSectionHeader=true;                    //  a new header must be created.
3018                     aNewSection.mpPageHdFt=NULL;
3019                 }
3020                 if (!aNewSection.mpPageHdFt)
3021                 {
3022                     String aName(RTL_CONSTASCII_STRINGPARAM("rtfHdFt"));
3023                     aName += String::CreateFromInt32(maSegments.size());
3024                     sal_uInt16 nPageNo = pDoc->MakePageDesc(aName);
3025                     aNewSection.mpPageHdFt = &pDoc->_GetPageDesc(nPageNo);
3026                     aNewSection.mbPageHdFtUsed = true;
3027                     maSegments.maDummyPageNos.push_back(nPageNo);
3028                 }
3029                 ReadHeaderFooter(nToken, aNewSection.mpPageHdFt);
3030                 if (_pKeepHeader) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepHeader);
3031                 if (_pKeepFooter) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepFooter);
3032                 break;
3033             case RTF_FOOTERF:
3034             case RTF_HEADERF:
3035                 if (!aNewSection.mpTitlePageHdFt)
3036                 {
3037                     String aTitle(RTL_CONSTASCII_STRINGPARAM("rtfTitleHdFt"));
3038                     aTitle += String::CreateFromInt32(maSegments.size());
3039                     sal_uInt16 nPageNo = pDoc->MakePageDesc(aTitle);
3040                     aNewSection.mpTitlePageHdFt = &pDoc->_GetPageDesc(nPageNo);
3041                     aNewSection.mbTitlePageHdFtUsed = true;
3042                     maSegments.maDummyPageNos.push_back(nPageNo);
3043                 }
3044                 ReadHeaderFooter(nToken, aNewSection.mpTitlePageHdFt);
3045                 break;
3046             case RTF_COLS:
3047                 aNewSection.mnCols = nTokenValue;
3048                 break;
3049             case RTF_COLSX:
3050                 aNewSection.mnColsx = nTokenValue;
3051                 break;
3052             case RTF_COLNO:
3053                 {
3054                     // next token must be either colw or colsr
3055                     unsigned long nAktCol = nValue;
3056                     long nWidth = 0, nSpace = 0;
3057                     int nColToken = GetNextToken();
3058                     if (RTF_COLW == nColToken)
3059                     {
3060                         // next token could be colsr (but not required)
3061                         nWidth = nTokenValue;
3062                         if( RTF_COLSR == GetNextToken() )
3063                             nSpace = nTokenValue;
3064                         else
3065                             SkipToken( -1 );        // put back token
3066                     }
3067                     else if (RTF_COLSR == nColToken)
3068                     {
3069                         // next token must be colw (what sense should it make to have colsr only?!)
3070                         nSpace = nTokenValue;
3071                         if( RTF_COLW == GetNextToken() )
3072                             nWidth = nTokenValue;
3073                         else
3074                             // what should we do if an isolated colsr without colw is found? Doesn't make sense!
3075                             SkipToken( -1 );        // put back token
3076                     }
3077                     else
3078                         break;
3079 
3080                     if (--nAktCol == (aNewSection.maColumns.size() / 2))
3081                     {
3082                         aNewSection.maColumns.push_back(nWidth);
3083                         aNewSection.maColumns.push_back(nSpace);
3084                     }
3085                 }
3086                 break;
3087             case RTF_STEXTFLOW:
3088                 aNewSection.mnStextflow = nTokenValue;
3089                 break;
3090             case RTF_RTLSECT:
3091                 aNewSection.mbRTLsection = true;
3092                 break;
3093             case RTF_LTRSECT:
3094                 aNewSection.mbRTLsection = false;
3095                 break;
3096             case '{':
3097                 {
3098                     short nSkip = 0;
3099                     if( RTF_IGNOREFLAG != ( nToken = GetNextToken() ))
3100                         nSkip = -1;
3101                     else if( RTF_SECTFMT != (( nToken = GetNextToken() )
3102                              & ~(0xff | RTF_SWGDEFS)) &&
3103                             ( RTF_DOCFMT != ( nToken & ~(0xff | RTF_SWGDEFS))) )
3104                         nSkip = -2;
3105                     else
3106                     {
3107                         // erstmal komplett ueberlesen
3108                         SkipGroup();
3109                         // ueberlese noch die schliessende Klammer
3110                         GetNextToken();
3111                     }
3112                     if (nSkip)
3113                     {
3114                         bWeiter = ((-1 == nSkip) &&
3115                             (
3116                               RTF_FOOTER == nToken || RTF_HEADER == nToken ||
3117                               RTF_FOOTERR == nToken || RTF_HEADERR == nToken ||
3118                               RTF_FOOTERL == nToken || RTF_HEADERL == nToken ||
3119                               RTF_FOOTERF == nToken || RTF_HEADERF == nToken
3120                             ));
3121                         SkipToken (nSkip);      // Ignore wieder zurueck
3122                     }
3123                 }
3124                 break;
3125             case RTF_PAPERW:
3126             case RTF_PAPERH:
3127             case RTF_MARGL:
3128             case RTF_MARGR:
3129             case RTF_MARGT:
3130             case RTF_MARGB:
3131             case RTF_FACINGP:
3132                 ASSERT(sal_False, "why are these tokens found in this section?");
3133                 ReadDocControls( nToken );
3134                 break;
3135             default:
3136                 if (RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)))
3137                     ReadDocControls( nToken );
3138                 else if (RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) ||
3139                          RTF_UNKNOWNCONTROL == nToken)
3140                 {
3141                     SvxRTFParser::NextToken(nToken);
3142                 }
3143                 else
3144                     bWeiter = false;
3145                 break;
3146         }
3147 
3148         if (bWeiter)
3149             nToken = GetNextToken();
3150     } while (bWeiter && IsParserWorking());
3151 
3152     if (bNewSection || maSegments.empty())
3153     {
3154         AttrGroupEnd(); //#106493#
3155         if(!bContainsPara && !bContainsTablePara) //#117881#: bContainsTablePara is set in rtftbl.cxx
3156             pDoc->AppendTxtNode(*pPam->GetPoint());
3157         bContainsPara = false;
3158         bContainsTablePara = false;
3159         maSegments.push_back(rtfSection(*pPam->GetPoint(), aNewSection));
3160     }
3161     else //modifying/replacing the current section
3162     {
3163         SwPaM aPamStart(maSegments.back().maStart);
3164         maSegments.pop_back();
3165         maSegments.push_back(rtfSection(*aPamStart.GetPoint(), aNewSection));
3166     }
3167 
3168     SkipToken(-1);
3169 }
3170 
EnterEnvironment()3171 void SwRTFParser::EnterEnvironment()
3172 {
3173 }
3174 
3175 
LeaveEnvironment()3176 void SwRTFParser::LeaveEnvironment()
3177 {
3178     if(pRedlineDelete)
3179     {
3180         delete pRedlineDelete;
3181         pRedlineDelete = 0;
3182     }
3183 
3184     if(pRedlineInsert)
3185     {
3186         delete pRedlineInsert;
3187         pRedlineInsert = 0;
3188     }
3189 }
3190 
SkipPageDescTbl()3191 void SwRTFParser::SkipPageDescTbl()
3192 {
3193     // M.M. #117907# I have to use this glorified SkipGroup because the
3194     // SvParser SkipGroup uses nNextCh which is not set correctly <groan>
3195     int nNumOpenBrakets = 1;
3196 
3197     while( nNumOpenBrakets && IsParserWorking() )
3198     {
3199         switch( GetNextToken() )
3200         {
3201         case '}':
3202             {
3203                 --nNumOpenBrakets;
3204             }
3205             break;
3206 
3207         case '{':
3208             {
3209                 nNumOpenBrakets++;
3210             }
3211             break;
3212         }
3213     }
3214 
3215     SkipToken( -1 );
3216 }
3217 
ReadPageDescTbl()3218 void SwRTFParser::ReadPageDescTbl()
3219 {
3220     // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections, damit
3221     // diese auch in den Headers/Footer benutzt werden koennen!
3222     MakeStyleTab();
3223     // das default-Style schon gleich am ersten Node setzen
3224     SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3225     if( !pColl )
3226         pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3227     pDoc->SetTxtFmtColl( *pPam, pColl );
3228 
3229     int nToken, bSaveChkStyleAttr = IsChkStyleAttr();
3230     int nNumOpenBrakets = 1;        // die erste wurde schon vorher erkannt !!
3231 
3232     SetChkStyleAttr(sal_False);     // Attribute nicht gegen die Styles checken
3233 
3234     bInPgDscTbl = true;
3235     sal_uInt16 nPos = 0;
3236     SwPageDesc* pPg = 0;
3237     SwFrmFmt* pPgFmt = 0;
3238 
3239     SvxULSpaceItem aUL( RES_UL_SPACE ), aHUL( RES_UL_SPACE ), aFUL( RES_UL_SPACE );
3240     SvxLRSpaceItem aLR( RES_LR_SPACE ), aHLR( RES_LR_SPACE ), aFLR( RES_LR_SPACE );
3241     Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
3242     SwFmtFrmSize aSz( ATT_FIX_SIZE, a4.Width(), a4.Height() );     // DIN A4 defaulten
3243     SwFmtFrmSize aFSz( ATT_MIN_SIZE ), aHSz( ATT_MIN_SIZE );
3244 
3245     SvxFrameDirectionItem aFrmDir(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR);
3246 
3247     sal_uInt16 nCols = USHRT_MAX, nColSpace = USHRT_MAX, nAktCol = 0;
3248     SvUShorts aColumns;
3249     ::std::map< const SwPageDesc*, sal_uInt16 > aFollowMap; //store index of following page descriptors
3250 
3251     while( nNumOpenBrakets && IsParserWorking() )
3252     {
3253         switch( nToken = GetNextToken() )
3254         {
3255         case '{':
3256             ++nNumOpenBrakets;
3257             break;
3258         case '}':
3259             if (1 == --nNumOpenBrakets)
3260             {
3261                 ASSERT(pPgFmt && pPg, "Serious problem here");
3262                 if (pPgFmt && pPg)
3263                 {
3264                     // PageDesc ist fertig, setze am Doc
3265                     pPgFmt->SetFmtAttr(aFrmDir);
3266                     pPgFmt->SetFmtAttr(aLR);
3267                     pPgFmt->SetFmtAttr(aUL);
3268                     pPgFmt->SetFmtAttr(aSz);
3269                     ::lcl_SetFmtCol(*pPgFmt, nCols, nColSpace, aColumns);
3270                     if (pPgFmt->GetHeader().GetHeaderFmt())
3271                     {
3272                         SwFrmFmt* pHFmt =
3273                             (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3274                         pHFmt->SetFmtAttr(aHUL);
3275                         pHFmt->SetFmtAttr(aHLR);
3276                         pHFmt->SetFmtAttr(aHSz);
3277                     }
3278                     if (pPgFmt->GetFooter().GetFooterFmt())
3279                     {
3280                         SwFrmFmt* pFFmt =
3281                             (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3282                         pFFmt->SetFmtAttr(aHUL);
3283                         pFFmt->SetFmtAttr(aHLR);
3284                         pFFmt->SetFmtAttr(aHSz);
3285                     }
3286                     if( nPos < pDoc->GetPageDescCnt() )
3287                         pDoc->ChgPageDesc(nPos++, *pPg);
3288                 }
3289             }
3290             break;
3291         case RTF_PGDSC:
3292             if (nPos)   // kein && wg MAC
3293             {
3294                 if (nPos != pDoc->MakePageDesc(
3295                     String::CreateFromInt32(nTokenValue)))
3296                 {
3297                     ASSERT( sal_False, "PageDesc an falscher Position" );
3298                 }
3299             }
3300             pPg = &pDoc->_GetPageDesc(nPos);
3301             pPg->SetLandscape( sal_False );
3302             pPgFmt = &pPg->GetMaster();
3303 #ifndef CFRONT
3304     SETPAGEDESC_DEFAULTS:
3305 #endif
3306             aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() );
3307             aLR.SetLeft( 0 );   aLR.SetRight( 0 );
3308             aUL.SetLower( 0 );  aUL.SetUpper( 0 );
3309             aHLR.SetLeft( 0 );  aHLR.SetRight( 0 );
3310             aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3311             aFLR.SetLeft( 0 );  aFLR.SetRight( 0 );
3312             aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3313             nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3314             aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3315             aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3316             break;
3317 
3318         case RTF_PGDSCUSE:
3319             pPg->WriteUseOn( (UseOnPage)nTokenValue );
3320             break;
3321 
3322         case RTF_PGDSCNXT:
3323             // store index of follow in map; will be fixed up later
3324             if( nTokenValue )
3325                 aFollowMap.insert( ::std::pair<const SwPageDesc*, sal_uInt16>( pPg, nTokenValue ));
3326             else
3327                 pPg->SetFollow( & const_cast<const SwDoc *>(pDoc)
3328                                 ->GetPageDesc( 0 ) );
3329             break;
3330 
3331         case RTF_FORMULA:   /* Zeichen "\|" !!! */
3332             pPgFmt->SetFmtAttr( aLR );
3333             pPgFmt->SetFmtAttr( aUL );
3334             pPgFmt->SetFmtAttr( aSz );
3335             ::lcl_SetFmtCol( *pPgFmt, nCols, nColSpace, aColumns );
3336             if( pPgFmt->GetHeader().GetHeaderFmt() )
3337             {
3338                 SwFrmFmt* pHFmt = (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt();
3339                 pHFmt->SetFmtAttr( aHUL );
3340                 pHFmt->SetFmtAttr( aHLR );
3341                 pHFmt->SetFmtAttr( aHSz );
3342             }
3343             if( pPgFmt->GetFooter().GetFooterFmt() )
3344             {
3345                 SwFrmFmt* pFFmt = (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt();
3346                 pFFmt->SetFmtAttr( aHUL );
3347                 pFFmt->SetFmtAttr( aHLR );
3348                 pFFmt->SetFmtAttr( aHSz );
3349             }
3350 
3351             pPgFmt = &pPg->GetLeft();
3352 #ifndef CFRONT
3353             goto SETPAGEDESC_DEFAULTS;
3354 #else
3355             aLR.SetLeft( 0 );   aLR.SetRight( 0 );
3356             aUL.SetLower( 0 );  aUL.SetUpper( 0 );
3357             aHLR.SetLeft( 0 );  aHLR.SetRight( 0 );
3358             aHUL.SetLower( 0 ); aHUL.SetUpper( 0 );
3359             aFLR.SetLeft( 0 );  aFLR.SetRight( 0 );
3360             aFUL.SetLower( 0 ); aFUL.SetUpper( 0 );
3361             aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); // DIN A4 default
3362             nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0;
3363             aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 );
3364             aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 );
3365             break;
3366 #endif
3367 
3368         case RTF_RTLSECT:
3369             aFrmDir.SetValue(FRMDIR_HORI_RIGHT_TOP);
3370             break;
3371 
3372         case RTF_LTRSECT:
3373             aFrmDir.SetValue(FRMDIR_HORI_LEFT_TOP);
3374             break;
3375 
3376         // alt: LI/RI/SA/SB, neu: MARG?SXN
3377         case RTF_MARGLSXN:
3378         case RTF_LI:        aLR.SetLeft( (sal_uInt16)nTokenValue );     break;
3379         case RTF_MARGRSXN:
3380         case RTF_RI:        aLR.SetRight( (sal_uInt16)nTokenValue );    break;
3381         case RTF_MARGTSXN:
3382         case RTF_SA:        aUL.SetUpper( (sal_uInt16)nTokenValue );    break;
3383         case RTF_MARGBSXN:
3384         case RTF_SB:        aUL.SetLower( (sal_uInt16)nTokenValue );    break;
3385         case RTF_PGWSXN:    aSz.SetWidth( nTokenValue );            break;
3386         case RTF_PGHSXN:    aSz.SetHeight( nTokenValue );           break;
3387 
3388         case RTF_HEADERY:       aHUL.SetUpper( (sal_uInt16)nTokenValue );   break;
3389         case RTF_HEADER_YB:     aHUL.SetLower( (sal_uInt16)nTokenValue );   break;
3390         case RTF_HEADER_XL:     aHLR.SetLeft( (sal_uInt16)nTokenValue );    break;
3391         case RTF_HEADER_XR:     aHLR.SetRight( (sal_uInt16)nTokenValue );   break;
3392         case RTF_FOOTERY:       aFUL.SetLower( (sal_uInt16)nTokenValue );   break;
3393         case RTF_FOOTER_YT:     aFUL.SetUpper( (sal_uInt16)nTokenValue );   break;
3394         case RTF_FOOTER_XL:     aFLR.SetLeft( (sal_uInt16)nTokenValue );    break;
3395         case RTF_FOOTER_XR:     aFLR.SetRight( (sal_uInt16)nTokenValue );   break;
3396 
3397         case RTF_HEADER_YH:
3398                 if( 0 > nTokenValue )
3399                 {
3400                     aHSz.SetHeightSizeType( ATT_FIX_SIZE );
3401                     nTokenValue = -nTokenValue;
3402                 }
3403                 aHSz.SetHeight( (sal_uInt16)nTokenValue );
3404                 break;
3405 
3406         case RTF_FOOTER_YH:
3407                 if( 0 > nTokenValue )
3408                 {
3409                     aFSz.SetHeightSizeType( ATT_FIX_SIZE );
3410                     nTokenValue = -nTokenValue;
3411                 }
3412                 aFSz.SetHeight( (sal_uInt16)nTokenValue );
3413                 break;
3414 
3415 
3416         case RTF_LNDSCPSXN:     pPg->SetLandscape( sal_True );          break;
3417 
3418         case RTF_COLS:          nCols = (sal_uInt16)nTokenValue;        break;
3419         case RTF_COLSX:         nColSpace = (sal_uInt16)nTokenValue;    break;
3420 
3421         case RTF_COLNO:
3422             nAktCol = (sal_uInt16)nTokenValue;
3423             if( RTF_COLW == GetNextToken() )
3424             {
3425                 sal_uInt16 nWidth = sal_uInt16( nTokenValue ), nSpace = 0;
3426                 if( RTF_COLSR == GetNextToken() )
3427                     nSpace = sal_uInt16( nTokenValue );
3428                 else
3429                     SkipToken( -1 );        // wieder zurueck
3430 
3431                 if( --nAktCol == ( aColumns.Count() / 2 ) )
3432                 {
3433                     aColumns.Insert( nWidth, aColumns.Count() );
3434                     aColumns.Insert( nSpace, aColumns.Count() );
3435                 }
3436             }
3437             break;
3438 
3439         case RTF_PAGEBB:
3440             {
3441                 pPgFmt->SetFmtAttr( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
3442             }
3443             break;
3444 
3445         case RTF_HEADER:
3446         case RTF_HEADERL:
3447         case RTF_HEADERR:
3448         case RTF_FOOTER:
3449         case RTF_FOOTERL:
3450         case RTF_FOOTERR:
3451         case RTF_FOOTERF:
3452         case RTF_HEADERF:
3453             ReadHeaderFooter(nToken, pPg);
3454             --nNumOpenBrakets;      // Klammer wird im ReadAttr ueberlesen!
3455             break;
3456         case RTF_TEXTTOKEN:
3457             if (!DelCharAtEnd(aToken, ';' ).Len())
3458                 break;
3459             ASSERT(pPg, "Unexpected missing pPg");
3460             if (pPg)
3461             {
3462                 pPg->SetName(aToken);
3463 
3464                 // sollte es eine Vorlage aus dem Pool sein ??
3465                 sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(aToken,
3466                     nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC);
3467                 if (USHRT_MAX != n)
3468                 {
3469                     // dann setze bei der Neuen die entsp. PoolId
3470                     pPg->SetPoolFmtId(n);
3471                 }
3472             }
3473             break;
3474         case RTF_BRDBOX:
3475             if (3 == nNumOpenBrakets)
3476             {
3477                 ReadBorderAttr(SkipToken(-2),
3478                     (SfxItemSet&)pPgFmt->GetAttrSet());
3479                 --nNumOpenBrakets;      // Klammer wird im ReadAttr ueberlesen!
3480             }
3481             break;
3482         case RTF_SHADOW:
3483             if( 3 == nNumOpenBrakets )
3484             {
3485                 ReadAttr( SkipToken( -2 ), (SfxItemSet*)&pPgFmt->GetAttrSet() );
3486                 --nNumOpenBrakets;      // Klammer wird im ReadAttr ueberlesen!
3487             }
3488             break;
3489 
3490 
3491         default:
3492             if( (nToken & ~0xff ) == RTF_SHADINGDEF )
3493                 ReadBackgroundAttr( nToken, (SfxItemSet&)pPgFmt->GetAttrSet() );
3494             break;
3495         }
3496     }
3497 
3498 
3499     // setze jetzt noch bei allen die entsprechenden Follows !!
3500     // Die, die ueber die Tabelle eingelesen wurden und einen
3501     // Follow definiert haben, ist dieser als Tabposition im
3502     // Follow schon gesetzt.
3503     for( nPos = 0; nPos < pDoc->GetPageDescCnt(); ++nPos )
3504     {
3505         SwPageDesc* pPgDsc = &pDoc->_GetPageDesc( nPos );
3506         std::map< const SwPageDesc*, sal_uInt16 >::const_iterator aIter =
3507             aFollowMap.find( pPgDsc );
3508         if (aIter != aFollowMap.end())
3509         {
3510             if ((*aIter).second < pDoc->GetPageDescCnt())
3511                 pPgDsc->SetFollow(& const_cast<const SwDoc *>(pDoc)->GetPageDesc((*aIter).second));
3512         }
3513     }
3514 
3515     SetChkStyleAttr( bSaveChkStyleAttr );
3516 
3517     bInPgDscTbl = false;
3518     nAktPageDesc = 0;
3519     nAktFirstPageDesc = 0;
3520     bSwPageDesc = true;
3521     SkipToken( -1 );
3522 }
3523 
3524 // -------------- Methoden --------------------
3525 
3526 /*
3527 void SwRTFParser::ReadUnknownData()
3528 {
3529     SvRTFParser::ReadUnknownData();
3530 }
3531 
3532 void SwRTFParser::ReadOLEData()
3533 {
3534     SvRTFParser::ReadOLEData();
3535 }
3536 */
3537 
ReadPrtData()3538 void SwRTFParser::ReadPrtData()
3539 {
3540     while( IsParserWorking() )
3541     {
3542         int nToken = GetNextToken();
3543         if( (RTF_TEXTTOKEN != nToken) && ('}' == nToken) )
3544             break;
3545     }
3546 
3547     SkipToken( -1 );        // schliessende Klammer wieder zurueck!!
3548 }
3549 
SetHeader(SwFrmFmt * pHdFtFmt,sal_Bool bReuseOld)3550 static const SwNodeIndex* SetHeader(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld)
3551 {
3552     ASSERT(pHdFtFmt, "Impossible, no header");
3553     const SwFrmFmt* pExisting = bReuseOld ?
3554         pHdFtFmt->GetHeader().GetHeaderFmt() : 0;
3555     if (!pExisting)
3556     {
3557         //No existing header, create a new one
3558         pHdFtFmt->SetFmtAttr(SwFmtHeader(sal_True));
3559         pExisting = pHdFtFmt->GetHeader().GetHeaderFmt();
3560     }
3561     return pExisting->GetCntnt().GetCntntIdx();
3562 }
3563 
SetFooter(SwFrmFmt * pHdFtFmt,sal_Bool bReuseOld)3564 static const SwNodeIndex* SetFooter(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld)
3565 {
3566     ASSERT(pHdFtFmt, "Impossible, no footer");
3567     const SwFrmFmt* pExisting = bReuseOld ?
3568         pHdFtFmt->GetFooter().GetFooterFmt() : 0;
3569     if (!pExisting)
3570     {
3571         //No exist footer, create a new one
3572         pHdFtFmt->SetFmtAttr(SwFmtFooter(sal_True));
3573         pExisting = pHdFtFmt->GetFooter().GetFooterFmt();
3574     }
3575     return pExisting->GetCntnt().GetCntntIdx();
3576 }
3577 
3578 
ReadHeaderFooter(int nToken,SwPageDesc * pPageDesc)3579 void SwRTFParser::ReadHeaderFooter( int nToken, SwPageDesc* pPageDesc )
3580 {
3581     ASSERT( RTF_FOOTNOTE == nToken ||
3582             RTF_FLY_INPARA == nToken ||
3583             pPageDesc, "PageDesc is missing" );
3584 
3585     bool bContainsParaCache = bContainsPara;
3586     // backup all important data
3587     SwPosition aSavePos( *pPam->GetPoint() );
3588     SvxRTFItemStack aSaveStack(GetAttrStack());
3589     GetAttrStack().clear();
3590 
3591     // save the fly array - after read, all flys may be set into
3592     // the header/footer
3593     SwFlySaveArr aSaveArray( 255 < aFlyArr.Count() ? aFlyArr.Count() : 255 );
3594     aSaveArray.Insert( &aFlyArr, 0 );
3595     aFlyArr.Remove( 0, aFlyArr.Count() );
3596     sal_Bool bSetFlyInDoc = sal_True;
3597 
3598     const SwNodeIndex* pSttIdx = 0;
3599     SwFrmFmt* pHdFtFmt = 0;
3600     SwTxtAttr* pTxtAttr = 0;
3601     int bDelFirstChar = sal_False;
3602     bool bOldIsFootnote = mbIsFootnote;
3603     sal_Bool bOldGrpStt = sal::static_int_cast< sal_Bool, int >(IsNewGroup());
3604 
3605     int nNumOpenBrakets = GetOpenBrakets() - 1;
3606 
3607     switch( nToken )
3608     {
3609     case RTF_FOOTNOTE:
3610         {
3611             bool bIsEndNote = RTF_FTNALT == GetNextToken();
3612             if (!bIsEndNote)
3613                 SkipToken(-1);
3614 
3615             SwTxtNode* pTxtNd = pPam->GetNode()->GetTxtNode();
3616             SwFmtFtn aFtnNote(bIsEndNote);
3617             xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3618 
3619             if (nPos && !bFootnoteAutoNum)
3620             {
3621                 pPam->GetPoint()->nContent--;
3622                 nPos--;
3623                 aFtnNote.SetNumStr( pTxtNd->GetTxt().GetChar( nPos ) );
3624                 ((String&)pTxtNd->GetTxt()).SetChar( nPos, CH_TXTATR_INWORD );
3625                 bDelFirstChar = sal_True;
3626             }
3627 
3628             pTxtAttr = pTxtNd->InsertItem( aFtnNote, nPos, nPos,
3629                         bDelFirstChar ? nsSetAttrMode::SETATTR_NOTXTATRCHR : 0 );
3630 
3631             ASSERT( pTxtAttr, "konnte die Fussnote nicht einfuegen/finden" );
3632 
3633             if( pTxtAttr )
3634                 pSttIdx = ((SwTxtFtn*)pTxtAttr)->GetStartNode();
3635             mbIsFootnote = true;
3636 
3637             // wurde an der Position ein Escapement aufgespannt, so entferne
3638             // das jetzt. Fussnoten sind bei uns immer hochgestellt.
3639             SvxRTFItemStackTypePtr pTmp = aSaveStack.empty() ? 0 : aSaveStack.back();
3640             if( pTmp && pTmp->GetSttNodeIdx() ==
3641                 pPam->GetPoint()->nNode.GetIndex() &&
3642                 pTmp->GetSttCnt() == nPos )
3643                 pTmp->GetAttrSet().ClearItem( RES_CHRATR_ESCAPEMENT );
3644         }
3645         break;
3646 
3647     case RTF_FLY_INPARA:
3648         {
3649             xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex();
3650             SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
3651                                             RES_FRMATR_END-1 );
3652             aSet.Put( SwFmtAnchor( FLY_AS_CHAR ));
3653             pHdFtFmt = pDoc->MakeFlySection( FLY_AS_CHAR,
3654                             pPam->GetPoint(), &aSet );
3655 
3656             pTxtAttr = pPam->GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
3657                                                 nPos, RES_TXTATR_FLYCNT );
3658             ASSERT( pTxtAttr, "konnte den Fly nicht einfuegen/finden" );
3659 
3660             pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
3661             bSetFlyInDoc = sal_False;
3662         }
3663         break;
3664 
3665     case RTF_HEADERF:
3666     case RTF_HEADER:
3667         pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_HEADERSHARE) );
3668         pHdFtFmt = &pPageDesc->GetMaster();
3669         pSttIdx = SetHeader( pHdFtFmt, sal_False );
3670         break;
3671 
3672     case RTF_HEADERL:
3673         // we cannot have left or right, must have always both
3674         pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3675         SetHeader( pPageDesc->GetRightFmt(), sal_True );
3676         pHdFtFmt = pPageDesc->GetLeftFmt();
3677         pSttIdx = SetHeader(pHdFtFmt, sal_False );
3678         break;
3679 
3680     case RTF_HEADERR:
3681         // we cannot have left or right, must have always both
3682         pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL));
3683         SetHeader( pPageDesc->GetLeftFmt(), sal_True );
3684         pHdFtFmt = pPageDesc->GetRightFmt();
3685         pSttIdx = SetHeader(pHdFtFmt, sal_False );
3686         break;
3687 
3688     case RTF_FOOTERF:
3689     case RTF_FOOTER:
3690         pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_FOOTERSHARE) );
3691         pHdFtFmt = &pPageDesc->GetMaster();
3692         pSttIdx = SetFooter(pHdFtFmt, sal_False );
3693         break;
3694 
3695     case RTF_FOOTERL:
3696         // we cannot have left or right, must have always both
3697         pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3698         SetFooter( pPageDesc->GetRightFmt(), sal_True );
3699         pHdFtFmt = pPageDesc->GetLeftFmt();
3700         pSttIdx = SetFooter(pHdFtFmt, sal_False );
3701         break;
3702 
3703     case RTF_FOOTERR:
3704         // we cannot have left or right, must have always both
3705         pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL));
3706         SetFooter( pPageDesc->GetLeftFmt(), sal_True );
3707         pHdFtFmt = pPageDesc->GetRightFmt();
3708         pSttIdx = SetFooter(pHdFtFmt, sal_False );
3709         break;
3710     }
3711 
3712     sal_uInt16 nOldFlyArrCnt = aFlyArr.Count();
3713     if( !pSttIdx )
3714         SkipGroup();
3715     else
3716     {
3717         // es ist auf jedenfall jetzt ein TextNode im Kopf/Fusszeilen-Bereich
3718         // vorhanden. Dieser muss jetzt nur noch gefunden und der neue Cursor
3719         // dort hinein gesetzt werden.
3720         SwCntntNode *pNode = pDoc->GetNodes()[ pSttIdx->GetIndex()+1 ]->
3721                                 GetCntntNode();
3722 
3723         // immer ans Ende der Section einfuegen !!
3724         pPam->GetPoint()->nNode = *pNode->EndOfSectionNode();
3725         pPam->Move( fnMoveBackward );
3726 
3727         SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
3728         if( !pColl )
3729             pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3730         pDoc->SetTxtFmtColl( *pPam, pColl );
3731 
3732         SetNewGroup( sal_True );
3733 
3734         while( !( nNumOpenBrakets == GetOpenBrakets() && !GetStackPos()) && IsParserWorking() )
3735         {
3736             switch( nToken = GetNextToken() )
3737             {
3738             case RTF_U:
3739                 if( bDelFirstChar )
3740                 {
3741                     bDelFirstChar = sal_False;
3742                     nToken = 0;
3743                 }
3744                 break;
3745 
3746             case RTF_TEXTTOKEN:
3747                 if( bDelFirstChar )
3748                 {
3749                     if( !aToken.Erase( 0, 1 ).Len() )
3750                         nToken = 0;
3751                     bDelFirstChar = sal_False;
3752                 }
3753                 break;
3754             }
3755             if( nToken )
3756                 NextToken( nToken );
3757         }
3758 
3759         SetAllAttrOfStk();
3760         if( aFlyArr.Count() && bSetFlyInDoc )
3761             SetFlysInDoc();
3762 
3763         // sollte der letze Node leer sein, dann loesche ihn
3764         // (\par heisst ja Absatzende und nicht neuer Absatz!)
3765         DelLastNode();
3766     }
3767 
3768     // vom FlyFmt noch die richtigen Attribute setzen
3769     if( pTxtAttr && RES_TXTATR_FLYCNT == pTxtAttr->Which() )
3770     {
3771         // is add a new fly ?
3772         if( nOldFlyArrCnt < aFlyArr.Count() )
3773         {
3774             SwFlySave* pFlySave = aFlyArr[ aFlyArr.Count()-1 ];
3775             pFlySave->aFlySet.ClearItem( RES_ANCHOR );
3776             pHdFtFmt->SetFmtAttr( pFlySave->aFlySet );
3777             aFlyArr.DeleteAndDestroy( aFlyArr.Count() - 1 );
3778         }
3779         else
3780         {
3781             // no, so remove the created textattribute
3782             SwFrmFmt* pFlyFmt = pTxtAttr->GetFlyCnt().GetFrmFmt();
3783             // remove the pam from the flynode
3784             *pPam->GetPoint() = aSavePos;
3785             pDoc->DelLayoutFmt( pFlyFmt );
3786         }
3787     }
3788 
3789     bFootnoteAutoNum = sal_False;       // default auf aus!
3790 
3791     // und alles wieder zurueck
3792     *pPam->GetPoint() = aSavePos;
3793     if (mbIsFootnote)
3794         SetNewGroup( bOldGrpStt );      // Status wieder zurueck
3795     else
3796         SetNewGroup( sal_False );           // { - Klammer war kein Group-Start!
3797     mbIsFootnote = bOldIsFootnote;
3798     GetAttrStack() = aSaveStack;
3799 
3800     aFlyArr.Insert( &aSaveArray, 0 );
3801     aSaveArray.Remove( 0, aSaveArray.Count() );
3802     bContainsPara = bContainsParaCache;
3803 }
3804 
SetSwgValues(SfxItemSet & rSet)3805 void SwRTFParser::SetSwgValues( SfxItemSet& rSet )
3806 {
3807     const SfxPoolItem* pItem;
3808     // Escapement korrigieren
3809     if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ESCAPEMENT, sal_False, &pItem ))
3810     {
3811         /* prozentuale Veraenderung errechnen !
3812             * Formel :      (FontSize * 1/20 ) pts      Escapement * 2
3813             *               -----------------------  = ----------------
3814             *                     100%                          x
3815             */
3816 
3817         // die richtige
3818         long nEsc = ((SvxEscapementItem*)pItem)->GetEsc();
3819 
3820         // automatische Ausrichtung wurde schon richtig berechnet
3821         if( DFLT_ESC_AUTO_SUPER != nEsc && DFLT_ESC_AUTO_SUB != nEsc )
3822         {
3823             const SvxFontHeightItem& rFH = GetSize( rSet );
3824             nEsc *= 1000L;
3825             if(rFH.GetHeight()) nEsc /= long(rFH.GetHeight()); // #i77256#
3826 
3827             SvxEscapementItem aEsc( (short) nEsc,
3828                                 ((SvxEscapementItem*)pItem)->GetProp(), RES_CHRATR_ESCAPEMENT);
3829             rSet.Put( aEsc );
3830         }
3831     }
3832 
3833     // TabStops anpassen
3834     if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, sal_False, &pItem ))
3835     {
3836         const SvxLRSpaceItem& rLR = GetLRSpace( rSet );
3837         SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem );
3838 
3839         long nOffset = rLR.GetTxtLeft();
3840         if( nOffset )
3841         {
3842             // Tabs anpassen !!
3843             SvxTabStop* pTabs = (SvxTabStop*)aTStop.GetStart();
3844             for( sal_uInt16 n = aTStop.Count(); n; --n, ++pTabs)
3845                 if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() )
3846                     pTabs->GetTabPos() -= nOffset;
3847 
3848             // negativer Einzug, dann auf 0 Pos einen Tab setzen
3849             if( rLR.GetTxtFirstLineOfst() < 0 )
3850                 aTStop.Insert( SvxTabStop() );
3851         }
3852 
3853         if( !aTStop.Count() )
3854         {
3855             const SvxTabStopItem& rDflt = (const SvxTabStopItem&)rSet.
3856                                 GetPool()->GetDefaultItem(RES_PARATR_TABSTOP);
3857             if( rDflt.Count() )
3858                 aTStop.Insert( &rDflt, 0 );
3859         }
3860         rSet.Put( aTStop );
3861     }
3862     else if( SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, sal_False, &pItem )
3863             && ((SvxLRSpaceItem*)pItem)->GetTxtFirstLineOfst() < 0 )
3864     {
3865         // negativer Einzug, dann auf 0 Pos einen Tab setzen
3866         rSet.Put( SvxTabStopItem( 1, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP ));
3867     }
3868 
3869     // NumRules anpassen
3870     if( !bStyleTabValid &&
3871         SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, sal_False, &pItem ))
3872     {
3873         // dann steht im Namen nur ein Verweis in das ListArray
3874         SwNumRule* pRule = GetNumRuleOfListNo( ((SwNumRuleItem*)pItem)->
3875                                                 GetValue().ToInt32() );
3876         if( pRule )
3877             rSet.Put( SwNumRuleItem( pRule->GetName() ));
3878         else
3879             rSet.ClearItem( RES_PARATR_NUMRULE );
3880 
3881     }
3882 
3883 
3884 /*
3885  ????????????????????????????????????????????????????????????????????
3886  ?? muss die LineSpacing Hoehe 200Twip betragen ??
3887  ?? in rtfitem.hxx wird es auf 0 defaultet. Wenn ja, dann muss hier
3888  ?? ein neues Item gesetzt werden!!!!
3889  ????????????????????????????????????????????????????????????????????
3890 
3891     // LineSpacing korrigieren
3892     if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_LINESPACING, sal_False, &pItem ))
3893     {
3894         const SvxLineSpacingItem* pLS = (const SvxLineSpacingItem*)pItem;
3895         SvxLineSpacingItem aNew;
3896 
3897         aNew.SetInterLineSpace( pLS->GetInterLineSpace() );
3898         aNew.GetLineSpaceRule() = pLS->GetLineSpaceRule();
3899         aNew.SetPropLineSpace( pLS->GetPropLineSpace() );
3900         aNew.GetInterLineSpaceRule() = pLS->GetInterLineSpaceRule();
3901 
3902         rSet.Put( aNew );
3903     }
3904 ?????????????????????????????????????????????????????????????????? */
3905 
3906 }
3907 
3908 
MakeColl(const String & rName,sal_uInt16 nPos,sal_uInt8 nOutlineLevel,bool & rbCollExist)3909 SwTxtFmtColl* SwRTFParser::MakeColl(const String& rName, sal_uInt16 nPos,
3910     sal_uInt8 nOutlineLevel, bool& rbCollExist)
3911 {
3912 	if( sal_uInt8(-1) == nOutlineLevel )
3913 		//nOutlineLevel = NO_NUMBERING;
3914 		nOutlineLevel = MAXLEVEL;//#outline level,zhaojianwei
3915 
3916 	rbCollExist = false;
3917     SwTxtFmtColl* pColl;
3918     String aNm( rName );
3919     if( !aNm.Len() )
3920     {
3921         ASSERT(sal_False, "not a bug, but I (cmc) want to see an example of this");
3922         if( !nPos )
3923         {
3924             pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
3925             if ( nOutlineLevel < MAXLEVEL )
3926                 pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
3927             else
3928                 pColl->DeleteAssignmentToListLevelOfOutlineStyle();
3929             return pColl;
3930         }
3931 
3932 		// erzeuge einen Namen
3933 		aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
3934 		aNm += String::CreateFromInt32( nPos );
3935 		aNm += ')';
3936 	}
3937     ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
3938     sw::util::ParaStyleMapper::StyleResult aResult =
3939         maParaStyleMapper.GetStyle(rName, eSti);
3940     pColl = aResult.first;
3941     rbCollExist = aResult.second;
3942     if (IsNewDoc() && rbCollExist)
3943     {
3944         // --> OD 2007-01-25 #i73790# - method renamed
3945         pColl->ResetAllFmtAttr();
3946         // <--
3947         rbCollExist = false;
3948     }
3949 
3950     if (!rbCollExist)
3951     {
3952     	//pColl->SetOutlineLevel( nOutlineLevel );	//#outline level,removed by zhaojianwei
3953 		if(nOutlineLevel < MAXLEVEL)						//->add by zhaojianwei
3954 			pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel );
3955 		else
3956 			pColl->DeleteAssignmentToListLevelOfOutlineStyle();	//<-end,zhaojianwei
3957     }
3958 
3959     return pColl;
3960 }
3961 
MakeCharFmt(const String & rName,sal_uInt16 nPos,int & rbCollExist)3962 SwCharFmt* SwRTFParser::MakeCharFmt(const String& rName, sal_uInt16 nPos,
3963                                     int& rbCollExist)
3964 {
3965     rbCollExist = sal_False;
3966     SwCharFmt* pFmt;
3967     String aNm( rName );
3968     if( !aNm.Len() )
3969     {
3970         ASSERT(sal_False, "not a bug, but I (cmc) want to see an example of this");
3971         aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" ));
3972         aNm += String::CreateFromInt32( nPos );
3973         aNm += ')';
3974     }
3975 
3976     ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName);
3977     sw::util::CharStyleMapper::StyleResult aResult =
3978         maCharStyleMapper.GetStyle(rName, eSti);
3979     pFmt = aResult.first;
3980     rbCollExist = aResult.second;
3981     if (IsNewDoc() && rbCollExist)
3982     {
3983         // --> OD 2007-01-25 #i73790# - method renamed
3984         pFmt->ResetAllFmtAttr();
3985         // <--
3986         rbCollExist = false;
3987     }
3988     return pFmt;
3989 }
3990 
SetStyleAttr(SfxItemSet & rCollSet,const SfxItemSet & rStyleSet,const SfxItemSet & rDerivedSet)3991 void SwRTFParser::SetStyleAttr( SfxItemSet& rCollSet,
3992                                 const SfxItemSet& rStyleSet,
3993                                 const SfxItemSet& rDerivedSet )
3994 {
3995     rCollSet.Put( rStyleSet );
3996     if( rDerivedSet.Count() )
3997     {
3998         // suche alle Attribute, die neu gesetzt werden:
3999         const SfxPoolItem* pItem;
4000         SfxItemIter aIter( rDerivedSet );
4001         sal_uInt16 nWhich = aIter.GetCurItem()->Which();
4002         while( sal_True )
4003         {
4004             switch( rStyleSet.GetItemState( nWhich, sal_False, &pItem ) )
4005             {
4006             case SFX_ITEM_DEFAULT:
4007                 // auf default zuruecksetzen
4008                 if( RES_FRMATR_END > nWhich )
4009                     rCollSet.Put( rCollSet.GetPool()->GetDefaultItem( nWhich ));
4010                 break;
4011             case SFX_ITEM_SET:
4012                 if( *pItem == *aIter.GetCurItem() )     // gleiches Attribut?
4013                     // definition kommt aus dem Parent
4014                     rCollSet.ClearItem( nWhich );       // loeschen
4015                 break;
4016             }
4017 
4018             if( aIter.IsAtEnd() )
4019                 break;
4020             nWhich = aIter.NextItem()->Which();
4021         }
4022     }
4023     // und jetzt noch auf unsere Werte abgleichen
4024     SetSwgValues( rCollSet );
4025 }
4026 
MakeStyle(sal_uInt16 nNo,const SvxRTFStyleType & rStyle)4027 SwTxtFmtColl* SwRTFParser::MakeStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle)
4028 {
4029     bool bCollExist;
4030     SwTxtFmtColl* pColl = MakeColl( rStyle.sName, sal_uInt16(nNo),
4031         rStyle.nOutlineNo, bCollExist);
4032     aTxtCollTbl.Insert( nNo, pColl );
4033 
4034     // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4035     if( bCollExist )
4036         return pColl;
4037 
4038     sal_uInt16 nStyleNo = rStyle.nBasedOn;
4039     if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4040     {
4041         SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4042         SwTxtFmtColl* pDerivedColl = aTxtCollTbl.Get( nStyleNo );
4043         if( !pDerivedColl )         // noch nicht vorhanden, also anlegen
4044         {
4045             // ist die ueberhaupt als Style vorhanden ?
4046             pDerivedColl = pDerivedStyle
4047                     ? MakeStyle( nStyleNo, *pDerivedStyle )
4048                     : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4049         }
4050 
4051         if( pColl == pDerivedColl )
4052             ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4053         else
4054         {
4055             pColl->SetDerivedFrom( pDerivedColl );
4056 
4057             // setze die richtigen Attribute
4058             const SfxItemSet* pDerivedSet;
4059             if( pDerivedStyle )
4060                 pDerivedSet = &pDerivedStyle->aAttrSet;
4061             else
4062                 pDerivedSet = &pDerivedColl->GetAttrSet();
4063 
4064             SetStyleAttr( (SfxItemSet&)pColl->GetAttrSet(),
4065                             rStyle.aAttrSet, *pDerivedSet );
4066         }
4067     }
4068     else
4069         ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet );
4070 
4071 
4072     nStyleNo = rStyle.nNext;
4073     if( nStyleNo != nNo )
4074     {
4075         SwTxtFmtColl* pNext = aTxtCollTbl.Get( nStyleNo );
4076         if( !pNext )            // noch nicht vorhanden, also anlegen
4077         {
4078             // ist die ueberhaupt als Style vorhanden ?
4079             SvxRTFStyleType* pMkStyle = GetStyleTbl().Get( nStyleNo );
4080             pNext = pMkStyle
4081                     ? MakeStyle( nStyleNo, *pMkStyle )
4082                     : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
4083         }
4084         pColl->SetNextTxtFmtColl( *pNext );
4085     }
4086     return pColl;
4087 }
4088 
MakeCharStyle(sal_uInt16 nNo,const SvxRTFStyleType & rStyle)4089 SwCharFmt* SwRTFParser::MakeCharStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle )
4090 {
4091     int bCollExist;
4092     SwCharFmt* pFmt = MakeCharFmt( rStyle.sName, sal_uInt16(nNo), bCollExist );
4093     aCharFmtTbl.Insert( nNo, pFmt );
4094 
4095     // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen
4096     if( bCollExist )
4097         return pFmt;
4098 
4099     sal_uInt16 nStyleNo = rStyle.nBasedOn;
4100     if( rStyle.bBasedOnIsSet && nStyleNo != nNo )
4101     {
4102         SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo );
4103         SwCharFmt* pDerivedFmt = aCharFmtTbl.Get( nStyleNo );
4104         if( !pDerivedFmt )          // noch nicht vorhanden, also anlegen
4105         {
4106             // ist die ueberhaupt als Style vorhanden ?
4107             pDerivedFmt = pDerivedStyle
4108                     ? MakeCharStyle( nStyleNo, *pDerivedStyle )
4109                     : pDoc->GetDfltCharFmt();
4110         }
4111 
4112         if( pFmt == pDerivedFmt )
4113             ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4114         else
4115         {
4116             pFmt->SetDerivedFrom( pDerivedFmt );
4117 
4118             // setze die richtigen Attribute
4119             const SfxItemSet* pDerivedSet;
4120             if( pDerivedStyle )
4121                 pDerivedSet = &pDerivedStyle->aAttrSet;
4122             else
4123                 pDerivedSet = &pDerivedFmt->GetAttrSet();
4124 
4125             SetStyleAttr( (SfxItemSet&)pFmt->GetAttrSet(),
4126                             rStyle.aAttrSet, *pDerivedSet );
4127         }
4128     }
4129     else
4130         ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet );
4131 
4132     return pFmt;
4133 }
4134 
4135 // loesche den letzten Node (Tabelle/Fly/Ftn/..)
DelLastNode()4136 void SwRTFParser::DelLastNode()
4137 {
4138     // sollte der letze Node leer sein, dann loesche ihn
4139     // (\par heisst ja Absatzende und nicht neuer Absatz!)
4140 
4141     if( !pPam->GetPoint()->nContent.GetIndex() )
4142     {
4143         sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex();
4144         SwCntntNode* pCNd = pDoc->GetNodes()[ nNodeIdx ]->GetCntntNode();
4145         // paragraphs with page break information are not empty! see #117914# topic 1)
4146         if(const SfxPoolItem* pItem=&(pCNd->GetAttr( RES_PAGEDESC, sal_False)))
4147         {
4148             SwFmtPageDesc* pPageDescItem = ((SwFmtPageDesc*)pItem);
4149             if (pPageDescItem->GetPageDesc()!=NULL)
4150             return;
4151         }
4152 
4153         if( pCNd && pCNd->StartOfSectionIndex()+2 <
4154             pCNd->EndOfSectionIndex() )
4155         {
4156             if( !GetAttrStack().empty() )
4157             {
4158                 // Attribut Stack-Eintraege, muessen ans Ende des vorherigen
4159                 // Nodes verschoben werden.
4160                 sal_Bool bMove = sal_False;
4161                 for( size_t n = GetAttrStack().size(); n; )
4162                 {
4163                     SvxRTFItemStackType* pStkEntry = (SvxRTFItemStackType*)
4164                                                     GetAttrStack()[ --n ];
4165                     if( nNodeIdx == pStkEntry->GetSttNode().GetIdx() )
4166                     {
4167                         if( !bMove )
4168                         {
4169                             pPam->Move( fnMoveBackward );
4170                             bMove = sal_True;
4171                         }
4172                         pStkEntry->SetStartPos( SwxPosition( pPam ) );
4173                     }
4174                 }
4175                 if( bMove )
4176                     pPam->Move( fnMoveForward );
4177             }
4178             pPam->GetPoint()->nContent.Assign( 0, 0 );
4179             pPam->SetMark();
4180             pPam->DeleteMark();
4181 
4182             pDoc->GetNodes().Delete( pPam->GetPoint()->nNode );
4183         }
4184     }
4185 }
4186 
4187     // fuer Tokens, die im ReadAttr nicht ausgewertet werden
UnknownAttrToken(int nToken,SfxItemSet * pSet)4188 void SwRTFParser::UnknownAttrToken( int nToken, SfxItemSet* pSet )
4189 {
4190     switch( nToken )
4191     {
4192     case RTF_INTBL:
4193         {
4194             if( !pTableNode )           // Tabelle nicht mehr vorhanden ?
4195                 NewTblLine();           // evt. Line copieren
4196             else
4197             {
4198                 static int _do=0; //$flr See #117881# for explanation.
4199                 // Crsr nicht mehr in der Tabelle ?
4200                 if( !pPam->GetNode()->FindTableNode() && _do )
4201                 {
4202                     sal_uLong nOldPos = pPam->GetPoint()->nNode.GetIndex();
4203 
4204                     // dann wieder in die letzte Box setzen
4205                     // (kann durch einlesen von Flys geschehen!)
4206                     pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode();
4207                     pPam->Move( fnMoveBackward );
4208 
4209                     // alle Attribute, die schon auf den nachfolgen zeigen
4210                     // auf die neue Box umsetzen !!
4211                     SvxRTFItemStack& rAttrStk = GetAttrStack();
4212                     const SvxRTFItemStackType* pStk;
4213                     for( size_t n = 0; n < rAttrStk.size(); ++n )
4214                         if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == nOldPos &&
4215                             !pStk->GetSttCnt() )
4216                             ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) );
4217                 }
4218             }
4219         }
4220         break;
4221 
4222     case RTF_PAGEBB:
4223         {
4224             pSet->Put( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ));
4225         }
4226         break;
4227 
4228     case RTF_PGBRK:
4229         {
4230             pSet->Put( SvxFmtBreakItem( 1 == nTokenValue ?
4231                                 SVX_BREAK_PAGE_BOTH : SVX_BREAK_PAGE_AFTER, RES_BREAK ));
4232         }
4233         break;
4234 
4235     case RTF_PGDSCNO:
4236         if( IsNewDoc() && bSwPageDesc &&
4237             sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() )
4238         {
4239             const SwPageDesc* pPgDsc = &const_cast<const SwDoc *>(pDoc)
4240                 ->GetPageDesc( (sal_uInt16)nTokenValue );
4241             pDoc->InsertPoolItem( *pPam, SwFmtPageDesc( pPgDsc ), 0);
4242         }
4243         break;
4244     case RTF_CS:
4245         {
4246             SwCharFmt* pFmt = aCharFmtTbl.Get( nTokenValue );
4247             if( pFmt )
4248                 pSet->Put( SwFmtCharFmt( pFmt ));
4249         }
4250         break;
4251 
4252     case RTF_LS:
4253         if( -1 != nTokenValue )
4254         {
4255             if( bStyleTabValid )
4256             {
4257                 // dann ist auch die ListTabelle gueltig, also suche die
4258                 // enstprechende NumRule
4259                 SwNumRule* pRule = GetNumRuleOfListNo( nTokenValue );
4260                 if( pRule )
4261                     pSet->Put( SwNumRuleItem( pRule->GetName() ));
4262 
4263                 if( SFX_ITEM_SET != pSet->GetItemState( FN_PARAM_NUM_LEVEL, sal_False ))
4264                     pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 ));
4265             }
4266             else
4267             {
4268                 // wir sind in der Style-Definitions - Phase. Der Name
4269                 // wird dann spaeter umgesetzt
4270                                 //#117891# pSet->Put( SwNumRuleItem( String::CreateFromInt32( nTokenValue )));
4271             }
4272 
4273         }
4274         break;
4275 
4276     case RTF_ILVL:
4277     case RTF_SOUTLVL:
4278         {
4279             sal_uInt8 nLevel = MAXLEVEL <= nTokenValue ? MAXLEVEL - 1
4280                                                   : sal_uInt8( nTokenValue );
4281             pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, nLevel ));
4282         }
4283         break;
4284 
4285 /*
4286     case RTF_SBYS:
4287     case RTF_EXPND:
4288     case RTF_KEEP:
4289     case RTF_KEEPN:
4290 */
4291 
4292     }
4293 }
4294 
ReadInfo(const sal_Char * pChkForVerNo)4295 void SwRTFParser::ReadInfo( const sal_Char* pChkForVerNo )
4296 {
4297 sal_Char __READONLY_DATA aChkForVerNo[] = "StarWriter";
4298 
4299     // falls nicht schon was vorgegeben wurde, setzen wir unseren Namen
4300     // rein. Wenn das im Kommentar match, wird im Parser die VersionNummer
4301     // gelesen und gesetzt
4302     if( !pChkForVerNo )
4303         pChkForVerNo = aChkForVerNo;
4304 
4305     SvxRTFParser::ReadInfo( pChkForVerNo );
4306 }
4307 
ReadUserProperties()4308 void SwRTFParser::ReadUserProperties()
4309 {
4310     // For now we don't support user properties but at least the parser is here.
4311     // At the moment it just swallows the tokens to prevent them being displayed
4312     int nNumOpenBrakets = 1, nToken;
4313 
4314     while( nNumOpenBrakets && IsParserWorking() )
4315     {
4316         switch( nToken = GetNextToken() )
4317         {
4318         case '}':
4319              --nNumOpenBrakets;
4320              break;
4321         case '{':
4322             {
4323                 if( RTF_IGNOREFLAG != GetNextToken() )
4324                     nToken = SkipToken( -1 );
4325                 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
4326                     nToken = SkipToken( -2 );
4327                 else
4328                 {
4329                     // gleich herausfiltern
4330                     ReadUnknownData();
4331                     nToken = GetNextToken();
4332                     if( '}' != nToken )
4333                         eState = SVPAR_ERROR;
4334                     break;
4335                 }
4336                 ++nNumOpenBrakets;
4337             }
4338             break;
4339 
4340         case RTF_PROPNAME:
4341             SkipGroup();
4342             break;
4343 
4344         case RTF_PROPTYPE:
4345             break;
4346 
4347         case RTF_STATICVAL:
4348             SkipGroup();
4349              break;
4350 
4351 //      default:
4352         }
4353     }
4354 
4355     SkipToken( -1 );
4356 }
4357 
4358 
4359 #ifdef USED
SaveState(int nToken)4360 void SwRTFParser::SaveState( int nToken )
4361 {
4362     SvxRTFParser::SaveState( nToken );
4363 }
4364 
RestoreState()4365 void SwRTFParser::RestoreState()
4366 {
4367     SvxRTFParser::RestoreState();
4368 }
4369 #endif
4370 
4371 /**/
4372 
BookmarkPosition(const SwPaM & rPaM)4373 BookmarkPosition::BookmarkPosition(const SwPaM &rPaM)
4374     : maMkNode(rPaM.GetMark()->nNode),
4375     mnMkCntnt(rPaM.GetMark()->nContent.GetIndex())
4376 {
4377 }
4378 
BookmarkPosition(const BookmarkPosition & rEntry)4379 BookmarkPosition::BookmarkPosition(const BookmarkPosition &rEntry)
4380     : maMkNode(rEntry.maMkNode), mnMkCntnt(rEntry.mnMkCntnt)
4381 {
4382 }
4383 
operator ==(const BookmarkPosition rhs)4384 bool BookmarkPosition::operator==(const BookmarkPosition rhs)
4385 {
4386     return(maMkNode.GetIndex() == rhs.maMkNode.GetIndex() && mnMkCntnt == rhs.mnMkCntnt);
4387 }
4388 
GetIdx() const4389 sal_uLong SwNodeIdx::GetIdx() const
4390 {
4391     return aIdx.GetIndex();
4392 }
4393 
Clone() const4394 SvxNodeIdx* SwNodeIdx::Clone() const
4395 {
4396     return new SwNodeIdx( aIdx );
4397 }
4398 
Clone() const4399 SvxPosition* SwxPosition::Clone() const
4400 {
4401     return new SwxPosition( pPam );
4402 }
4403 
MakeNodeIdx() const4404 SvxNodeIdx* SwxPosition::MakeNodeIdx() const
4405 {
4406     return new SwNodeIdx( pPam->GetPoint()->nNode );
4407 }
4408 
GetNodeIdx() const4409 sal_uLong   SwxPosition::GetNodeIdx() const
4410 {
4411     return pPam->GetPoint()->nNode.GetIndex();
4412 }
4413 
GetCntIdx() const4414 xub_StrLen SwxPosition::GetCntIdx() const
4415 {
4416     return pPam->GetPoint()->nContent.GetIndex();
4417 }
4418 
4419 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
4420