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