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