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