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