xref: /AOO42X/main/sw/source/filter/ww1/fltshell.cxx (revision b1c5455db1639c48e26c568e4fa7ee78ca5d60ee)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <ctype.h>
28 #include <hintids.hxx>
29 #include <hints.hxx>
30 #include <svtools/filter.hxx>
31 
32 #include <vcl/graph.hxx>
33 #include <svl/urihelper.hxx>
34 #include <editeng/boxitem.hxx>
35 #include <editeng/boxitem.hxx>
36 #include <editeng/wghtitem.hxx>
37 #include <editeng/cmapitem.hxx>
38 #include <editeng/cntritem.hxx>
39 #include <editeng/postitem.hxx>
40 #include <editeng/crsditem.hxx>
41 #include <svl/stritem.hxx>
42 #include <unotools/charclass.hxx>
43 #include <txtftn.hxx>
44 #include <fmtpdsc.hxx>
45 #include <fmtftn.hxx>
46 #include <fmtanchr.hxx>
47 #include <fmtrfmrk.hxx>
48 #include <fmtclds.hxx>
49 #include <fmtfld.hxx>
50 #include <fmtfsize.hxx>
51 #include <fmthdft.hxx>
52 #include <fmtcntnt.hxx>
53 #include <redline.hxx>
54 #include <pam.hxx>
55 #include <doc.hxx>
56 #include <ndtxt.hxx>
57 #include <frmatr.hxx>
58 #include <fldbas.hxx>           // RES_SETEXPFLD
59 #include <charatr.hxx>          // class SwFmtRefMark
60 #include <swtable.hxx>          // class SwTableLines, ...
61 #include <tox.hxx>
62 #include <expfld.hxx>           // SwExpField
63 #include <section.hxx>          // class SwSection
64 #include <tblsel.hxx>           // class SwSelBoxes
65 #include <pagedesc.hxx>
66 #include <docsh.hxx>            // class SwDocSh
67 #include <fltshell.hxx>
68 #include <viewsh.hxx>
69 #include <shellres.hxx>
70 
71 
72 #define MAX_FIELDLEN 64000
73 
74 using namespace com::sun::star;
75 
GetCntntNode(SwDoc * pDoc,SwNodeIndex & rIdx,sal_Bool bNext)76 static SwCntntNode* GetCntntNode(SwDoc* pDoc, SwNodeIndex& rIdx, sal_Bool bNext)
77 {
78     SwCntntNode * pCNd = rIdx.GetNode().GetCntntNode();
79     if(!pCNd && 0 == (pCNd = bNext ? pDoc->GetNodes().GoNext(&rIdx)
80                                      : pDoc->GetNodes().GoPrevious(&rIdx)))
81     {
82         pCNd = bNext ? pDoc->GetNodes().GoPrevious(&rIdx)
83                      : pDoc->GetNodes().GoNext(&rIdx);
84         ASSERT(pCNd, "kein ContentNode gefunden");
85     }
86     return pCNd;
87 }
88 
89 // ------ Stack-Eintrag fuer die gesamten - Attribute vom Text -----------
SwFltStackEntry(const SwPosition & rStartPos,SfxPoolItem * pHt)90 SwFltStackEntry::SwFltStackEntry(const SwPosition& rStartPos, SfxPoolItem* pHt ) :
91     nMkNode(rStartPos.nNode, -1),
92     //Modify here for #119405, by easyfan, 2012-05-24
93     nPtNode(nMkNode),mnStartCP(-1),mnEndCP(-1),bIsParaEnd(false)
94     //End of modification, by easyfan
95 {
96     // Anfang vom Bereich merken
97     nMkCntnt = rStartPos.nContent.GetIndex();
98     pAttr = pHt;        // speicher eine Kopie vom Attribut
99     bOld    = sal_False;    // used for marking Attributes *before* skipping field results
100     bLocked = sal_True;     // locke das Attribut --> darf erst
101     bCopied = sal_False;    // gesetzt werden, wenn es wieder geunlocked ist
102     bConsumedByField = sal_False;
103 }
104 
SwFltStackEntry(const SwFltStackEntry & rEntry)105 SwFltStackEntry::SwFltStackEntry(const SwFltStackEntry& rEntry) :
106     nMkNode(rEntry.nMkNode),
107     nPtNode(rEntry.nPtNode)
108 {
109     pAttr   = rEntry.pAttr->Clone();
110     nMkCntnt= rEntry.nMkCntnt;
111     bOld    = rEntry.bOld;
112     bLocked = bCopied = sal_True; // when rEntry were NOT bLocked we would never have been called
113     bConsumedByField = rEntry.bConsumedByField;
114     //Modify here for #119405, by chengjh, 2012-08-16
115     mnStartCP= rEntry.mnStartCP;
116     mnEndCP = rEntry.mnEndCP;
117     bIsParaEnd = rEntry.bIsParaEnd;
118     //End
119 }
120 
121 
~SwFltStackEntry()122 SwFltStackEntry::~SwFltStackEntry()
123 {
124     // Attribut kam zwar als Pointer, wird aber hier geloescht
125     if (pAttr)
126         delete pAttr;
127 }
128 
SetEndPos(const SwPosition & rEndPos)129 void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos)
130 {
131     // Attribut freigeben und das Ende merken.
132     // Alles mit sal_uInt16's, weil sonst beim Einfuegen von neuem Text an der
133     // Cursor-Position auch der Bereich vom Attribut weiter
134     // verschoben wird.
135     // Das ist aber nicht das gewollte!
136     bLocked = sal_False;                    // freigeben und das ENDE merken
137     nPtNode = rEndPos.nNode.GetIndex()-1;
138     nPtCntnt = rEndPos.nContent.GetIndex();
139 }
140 //Modify here for #119405, by chengjh, 2012-08-16
141 //The only position of 0x0D will not be able to make regin in the old logic
142 //because it is beyond the length of para...need special consideration here.
IsAbleMakeRegion()143 bool SwFltStackEntry::IsAbleMakeRegion()
144 {
145     SwCntntNode *const pCntntNode( SwNodeIndex(nMkNode, +1).GetNode().GetCntntNode() );
146     if ( (nMkNode.GetIndex() == nPtNode.GetIndex())
147          && (nMkCntnt == nPtCntnt)
148          && ( (0 != nPtCntnt)
149               || ( pCntntNode
150                    && ( 0 != pCntntNode->Len() ) ) )
151          && ( RES_TXTATR_FIELD != pAttr->Which()
152               && RES_TXTATR_ANNOTATION != pAttr->Which()
153               && RES_TXTATR_INPUTFIELD != pAttr->Which() )
154          && !( bIsParaEnd
155                && pCntntNode
156                && pCntntNode->IsTxtNode()
157                && 0 != pCntntNode->Len() ) )
158     {
159         return false;
160     }
161 
162     return true;
163 }
164 //End
MakeRegion(SwDoc * pDoc,SwPaM & rRegion,sal_Bool bCheck)165 sal_Bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, sal_Bool bCheck )
166 {
167     // does this range actually contain something?
168     // empty range is allowed if at start of empty paragraph
169     // fields are special: never have range, so leave them
170     //Modify here for #119405, by chengjh, 2012-08-16
171     //Revised the code and move the code segment to defined function
172         if ( !IsAbleMakeRegion() )
173     {
174         return sal_False;
175     }
176     //End
177     // !!! Die Content-Indizies beziehen sich immer auf den Node !!!
178     rRegion.GetPoint()->nNode = nMkNode.GetIndex() + 1;
179     SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, sal_True);
180     rRegion.GetPoint()->nContent.Assign(pCNd, nMkCntnt);
181     rRegion.SetMark();
182     if( nMkNode != nPtNode )
183     {
184         rRegion.GetPoint()->nNode = nPtNode.GetIndex() + 1;
185         pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, sal_False);
186     }
187     rRegion.GetPoint()->nContent.Assign(pCNd, nPtCntnt);
188 #if OSL_DEBUG_LEVEL > 1
189     ASSERT( CheckNodesRange( rRegion.Start()->nNode,
190                              rRegion.End()->nNode, sal_True ),
191              "Attribut oder AEhnliches ueber Bereichs-Grenzen" );
192 #endif
193     if( bCheck )
194         return CheckNodesRange( rRegion.Start()->nNode,
195                                 rRegion.End()->nNode, sal_True );
196     else
197         return sal_True;
198 }
199 
SwFltControlStack(SwDoc * pDo,sal_uLong nFieldFl)200 SwFltControlStack::SwFltControlStack(SwDoc* pDo, sal_uLong nFieldFl)
201   : nFieldFlags(nFieldFl), bHasSdOD(true)
202   ,bSdODChecked(false), pDoc(pDo), bIsEndStack(false)
203     //End
204 
205 {
206 }
207 
208 
~SwFltControlStack()209 SwFltControlStack::~SwFltControlStack()
210 {
211     ASSERT(!Count(), "noch Attribute auf dem Stack");
212 }
213 
214 // MoveAttrs() ist fuer folgendes Problem:
215 // Wenn ueber den Stack ein Feld wie z.B. "Variable setzen" gesetzt wird,
216 // verschiebt sich der Text um ein \xff - Zeichen, und alle folgenden
217 // Attribute stimmen in ihrer Position nicht mehr.
218 // Dann muss MoveAttrs() nach dem Setzen des Attributes ins Doc gerufen werden,
219 // so dass alle Attribut-Positionen,
220 // die im selben Absatz weiter hinten stehen, um 1 Zeichen weiter
221 // nach rechts verschoben werden.
MoveAttrs(const SwPosition & rPos)222 void SwFltControlStack::MoveAttrs( const SwPosition& rPos )
223 {
224     sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
225     SwFltStackEntry* pEntry;
226     sal_uLong nPosNd = rPos.nNode.GetIndex();
227     sal_uInt16 nPosCt = rPos.nContent.GetIndex() - 1;
228 
229     for (sal_uInt16 i=0; i < nCnt; i++){
230         pEntry = (*this)[ i ];
231         if(( pEntry->nMkNode.GetIndex() + 1 == nPosNd )
232            &&( pEntry->nMkCntnt >= nPosCt )){
233             pEntry->nMkCntnt++;
234             ASSERT( pEntry->nMkCntnt
235                 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
236                     "Attribut-Anfang hinter Zeilenende" );
237         }
238         if(( pEntry->nPtNode.GetIndex() + 1 == nPosNd )
239            &&( pEntry->nPtCntnt >= nPosCt )){
240             pEntry->nPtCntnt++;
241             ASSERT( pEntry->nPtCntnt
242                 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
243                     "Attribut-Ende hinter Zeilenende" );
244         }
245     }
246 }
247 
MarkAllAttrsOld()248 void SwFltControlStack::MarkAllAttrsOld()
249 {
250     sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
251     for (sal_uInt16 i=0; i < nCnt; i++)
252         (*this)[ i ]->bOld = sal_True;
253 }
254 
NewAttr(const SwPosition & rPos,const SfxPoolItem & rAttr)255 void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem & rAttr )
256 {
257     SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() );
258     //Modify here for #119405, by easyfan, 2012-05-24
259     pTmp->SetStartCP(GetCurrAttrCP());
260     //End of modification, by easyfan
261     sal_uInt16 nWhich = pTmp->pAttr->Which();
262     SetAttr(rPos, nWhich);// Ende von evtl. gleichen Attributen auf dem Stack
263                                 // Setzen, damit sich die Attribute nicht auf
264                                 // dem Stack haeufen
265     maEntries.push_back(pTmp);
266 }
267 
DeleteAndDestroy(Entries::size_type nCnt)268 void SwFltControlStack::DeleteAndDestroy(Entries::size_type nCnt)
269 {
270     ASSERT(nCnt < maEntries.size(), "Out of range!");
271     if (nCnt < maEntries.size())
272     {
273         myEIter aElement = maEntries.begin() + nCnt;
274         delete *aElement;
275         maEntries.erase(aElement);
276     }
277     //Modify for #119405 by chengjh, 2012-08-16
278     //Clear the para end position recorded in reader intermittently for the least impact on loading performance
279     //Because the attributes handled based on the unit of para
280     if ( Count() == 0 )
281     {
282         ClearParaEndPosition();
283         bHasSdOD = true;
284         bSdODChecked = false;
285     }
286     //End
287 }
288 
289 // SwFltControlStack::StealAttr() loescht Attribute des angegebenen Typs vom Stack.
290 // Als nAttrId sind erlaubt: 0 fuer alle, oder ein spezieller Typ.
291 // Damit erscheinen sie nicht in der Doc-Struktur. Dabei werden nur die
292 // Attribute entfernt, die im selben Absatz wie pPos stehen.
293 // Wird fuer Grafik-Apos -> Grafiken benutzt.
StealAttr(const SwPosition * pPos,sal_uInt16 nAttrId)294 void SwFltControlStack::StealAttr(const SwPosition* pPos, sal_uInt16 nAttrId /* = 0 */)
295 {
296     sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
297 
298     SwFltStackEntry* pEntry;
299 
300     while (nCnt)
301     {
302         nCnt --;
303         pEntry = (*this)[ nCnt ];
304         if (pEntry->nPtNode.GetIndex()+1 == pPos->nNode.GetIndex() &&
305             (!nAttrId || nAttrId == pEntry->pAttr->Which()))
306             DeleteAndDestroy(nCnt);     // loesche aus dem Stack
307     }
308 }
309 
310 // SwFltControlStack::KillUnlockedAttr() loescht alle Attribute vom Stack,
311 // welche punktuell auf pPos aufgespannt sind.
312 // Damit erscheinen sie nicht in der Doc-Struktur.
313 // Wird im WW Import benoetigt zum ignorieren der auf dem 0x0c Section-
314 // Break-Symbol gesetzten Attribute.
KillUnlockedAttrs(const SwPosition & pPos)315 void SwFltControlStack::KillUnlockedAttrs(const SwPosition& pPos)
316 {
317     SwNodeIndex aAktNode( pPos.nNode, -1 );
318     sal_uInt16 nAktIdx = pPos.nContent.GetIndex();
319 
320     sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
321     SwFltStackEntry* pEntry;
322     while( nCnt )
323     {
324         nCnt --;
325         pEntry = (*this)[ nCnt ];
326         if(    !pEntry->bOld
327             && !pEntry->bLocked
328             && (pEntry->nMkNode  == aAktNode)
329             && (pEntry->nMkCntnt == nAktIdx )
330             && (pEntry->nPtNode  == aAktNode)
331             && (pEntry->nPtCntnt == nAktIdx ))
332         {
333             DeleteAndDestroy( nCnt ); // loesche aus dem Stack
334         }
335     }
336 }
337 
338 // Alle gelockten Attribute freigeben (unlocken) und das Ende setzen,
339 // alle anderen im Document setzen und wieder aus dem Stack loeschen
340 // Returned, ob das gesuchte Attribut / die gesuchten Attribute
341 // ueberhaupt auf dem Stack standen
SetAttr(const SwPosition & rPos,sal_uInt16 nAttrId,sal_Bool bTstEnde,long nHand,sal_Bool consumedByField)342 void SwFltControlStack::SetAttr(const SwPosition& rPos, sal_uInt16 nAttrId,
343                                 sal_Bool bTstEnde, long nHand, sal_Bool consumedByField )
344 {
345     ASSERT(!nAttrId ||
346         (POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) ||
347         (RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId),
348         "Falsche Id fuers Attribut")
349 
350     sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
351 
352     SwFltStackEntry* pEntry;
353 
354     for (sal_uInt16 i=0; i < nCnt; i++)
355     {
356         pEntry = (*this)[ i ];
357         if (pEntry->bLocked)
358         {
359             // setze das Ende vom Attribut
360             bool bF = false;
361             if (!nAttrId ){
362                 bF = true;
363             }else if( nAttrId == pEntry->pAttr->Which()){
364                 if( nAttrId != RES_FLTR_BOOKMARK ){     // Handle abfragen
365                     bF = true;
366                 }else if( nHand == ((SwFltBookmark*)(pEntry->pAttr))->GetHandle() )
367                 {
368                     bF = true;
369                 }
370             }
371             if (bF) {
372                 pEntry->bConsumedByField = consumedByField;
373                 pEntry->SetEndPos(rPos);
374                 //Modify here for #119405, by easyfan, 2012-05-24
375                 pEntry->SetEndCP(GetCurrAttrCP());
376                 //End of modification, by easyfan
377             }
378             continue;
379         }
380 
381         // ist die Endposition die Cursor-Position, dann noch nicht
382         // ins Dokument setzen, es muss noch Text folgen;
383         // ausser am Dokumentende. (Attribut-Expandierung !!)
384         // Beim Ende-Stack niemals ausser am DocEnde reinsetzen
385         if (bTstEnde)
386         {
387             if (bIsEndStack || pEntry->nPtNode.GetIndex()+1 ==
388                         rPos.nNode.GetIndex())
389             continue;
390         }
391         SetAttrInDoc(rPos, pEntry);
392         DeleteAndDestroy(i);        // loesche aus dem Stack
393         i--; nCnt--;        // Danach rutschen alle folgenden nach unten
394     }
395 }
396 
MakePoint(SwFltStackEntry * pEntry,SwDoc * pDoc,SwPaM & rRegion)397 static void MakePoint(SwFltStackEntry* pEntry, SwDoc* pDoc, SwPaM& rRegion)
398 {
399             // der Anker ist der Point vom Pam. Dieser wird beim Einfugen
400             // von Text usw. veraendert; darum wird er auf dem Stack
401             // gespeichert. Das Attribut muss nur noch im Format
402             // gesetzt werden.
403     rRegion.DeleteMark();
404     rRegion.GetPoint()->nNode = pEntry->nMkNode.GetIndex() + 1;
405     SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, sal_True);
406     rRegion.GetPoint()->nContent.Assign(pCNd, pEntry->nMkCntnt);
407 }
408 
409 // MakeBookRegionOrPoint() ist wie MakeRegionOrPoint, aber die besonderen
410 // Beschraenkungen von Bookmarks in Tabellen werden beachtet.
411 // ( Anfang und Ende muessen in selber Zelle sein )
MakeBookRegionOrPoint(SwFltStackEntry * pEntry,SwDoc * pDoc,SwPaM & rRegion,sal_Bool bCheck)412 static void MakeBookRegionOrPoint(SwFltStackEntry* pEntry, SwDoc* pDoc,
413                     SwPaM& rRegion, sal_Bool bCheck )
414 {
415     if (pEntry->MakeRegion(pDoc, rRegion, bCheck )){
416 //      sal_Bool b1 = rNds[rRegion.GetPoint()->nNode]->FindTableNode() != 0;
417 //      const SwStartNode* p1 = rNds[rRegion.GetPoint()->nNode]->FindTableBoxStartNode();
418 //      const SwStartNode* p2 = rNds[rRegion.GetMark()->nNode]->FindTableBoxStartNode();
419         if (rRegion.GetPoint()->nNode.GetNode().FindTableBoxStartNode()
420               != rRegion.GetMark()->nNode.GetNode().FindTableBoxStartNode())
421         {
422             rRegion.Exchange();         // Ungueltiger Bereich
423             rRegion.DeleteMark();       // -> beide auf Mark
424         }
425     }else{
426         MakePoint(pEntry, pDoc, rRegion);
427     }
428 }
429 
430 #if OSL_DEBUG_LEVEL > 1
431 extern sal_Bool CheckNodesRange( const SwNodeIndex& rStt,
432                     const SwNodeIndex& rEnd, sal_Bool bChkSection );
433 #endif
434 
435 // IterateNumrulePiece() sucht von rTmpStart bis rEnd den ersten
436 // fuer Numrules gueltigen Bereich heraus.
437 //
438 // rNds sind die Doc-Nodes
439 // rEnd ist Bereichs-Ende,
440 // rTmpStart ist ReinRaus-Parameter: Anfang des zu untersuchenden Bereiches rein,
441 //                                   Anfang des gueltigen Bereichs raus
442 // rTmpEnd ist raus-Parameter
443 // Return-Bool ist sal_True fuer gueltigen Bereich
IterateNumrulePiece(const SwNodeIndex & rEnd,SwNodeIndex & rTmpStart,SwNodeIndex & rTmpEnd)444 static sal_Bool IterateNumrulePiece( const SwNodeIndex& rEnd,
445                                 SwNodeIndex& rTmpStart, SwNodeIndex& rTmpEnd )
446 {
447     while( ( rTmpStart <= rEnd )
448            && !( rTmpStart.GetNode().IsTxtNode() ) )    // suche gueltigen Anfang
449         rTmpStart++;
450 
451     rTmpEnd = rTmpStart;
452     while( ( rTmpEnd <= rEnd )
453            && ( rTmpEnd.GetNode().IsTxtNode() ) )       // suche gueltiges Ende + 1
454         rTmpEnd++;
455 
456     rTmpEnd--;                                      // gueltiges Ende
457 
458     return rTmpStart <= rTmpEnd;                    // gueltig ?
459 }
460 //Modify for #119405 by chengjh, 2012-08-16
461 //***This function will check whether there is existing individual attribute positon for 0x0D***/
462 //The check will happen only once for a paragraph during loading
HasSdOD()463 bool SwFltControlStack::HasSdOD()
464 {
465     sal_uInt16 nCnt = static_cast< sal_uInt16 >(Count());
466 
467     SwFltStackEntry* pEntry = 0;
468 
469     bool bRet = false;
470 
471     for (sal_uInt16 i=0; i < nCnt; i++)
472     {
473         pEntry = (*this)[ i ];
474         if ( pEntry && pEntry->mnStartCP == pEntry->mnEndCP )
475         {
476             if ( CheckSdOD(pEntry->mnStartCP,pEntry->mnEndCP) )
477             {
478                 bRet = true;
479                 break;
480             }
481         }
482     }
483 
484     return bRet;
485 }
486 //End
SetAttrInDoc(const SwPosition & rTmpPos,SwFltStackEntry * pEntry)487 void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry* pEntry)
488 {
489     SwPaM aRegion( rTmpPos );
490 
491     switch(pEntry->pAttr->Which())
492     {
493     case RES_FLTR_ANCHOR:
494         {
495             SwFrmFmt* pFmt = ((SwFltAnchor*)pEntry->pAttr)->GetFrmFmt();
496             if (pFmt != NULL)
497             {
498                 MakePoint(pEntry, pDoc, aRegion);
499                 SwFmtAnchor aAnchor(pFmt->GetAnchor());
500                 aAnchor.SetAnchor(aRegion.GetPoint());
501                 pFmt->SetFmtAttr(aAnchor);
502                 // Damit die Frames bei Einfuegen in existierendes Doc
503                 //  erzeugt werden (erst nach Setzen des Ankers!):
504                 if(pDoc->GetCurrentViewShell()  //swmod 071108//swmod 071225
505                    && (FLY_AT_PARA == pFmt->GetAnchor().GetAnchorId()))
506                 {
507                     pFmt->MakeFrms();
508                 }
509             }
510         }
511         break;
512     case RES_FLTR_STYLESHEET:
513         break;
514 
515     case RES_TXTATR_FIELD:
516     case RES_TXTATR_ANNOTATION:
517     case RES_TXTATR_INPUTFIELD:
518         break;
519 
520     case RES_TXTATR_TOXMARK:
521         break;
522 
523     case RES_FLTR_NUMRULE:          // Numrule 'reinsetzen
524     {
525         const String& rNumNm = ( (SfxStringItem*) pEntry->pAttr )->GetValue();
526         SwNumRule* pNumRule = pDoc->FindNumRulePtr( rNumNm );
527         if ( pNumRule )
528         {
529             if ( pEntry->MakeRegion( pDoc, aRegion, sal_True ) )
530             {
531                 SwNodeIndex aTmpStart( aRegion.Start()->nNode );
532                 SwNodeIndex aTmpEnd( aTmpStart );
533                 SwNodeIndex& rRegEndNd = aRegion.End()->nNode;
534                 while (IterateNumrulePiece( rRegEndNd, aTmpStart, aTmpEnd ))
535                 {
536                     SwPaM aTmpPam( aTmpStart, aTmpEnd );
537                     pDoc->SetNumRule( aTmpPam, *pNumRule, false );
538 
539                     aTmpStart = aTmpEnd;    // Start fuer naechstes Teilstueck
540                     aTmpStart++;
541                 }
542             }
543             else
544                 pDoc->DelNumRule( rNumNm );
545         }
546     }
547         break;
548 
549     case RES_FLTR_NUMRULE_NUM:
550         break;
551     case RES_FLTR_BOOKMARK:
552         {
553             SwFltBookmark* pB = (SwFltBookmark*)pEntry->pAttr;
554             const String& rName = ((SwFltBookmark*)pEntry->pAttr)->GetName();
555 
556             if (IsFlagSet(BOOK_TO_VAR_REF))
557             {
558                 SwFieldType* pFT = pDoc->GetFldType(RES_SETEXPFLD, rName, false);
559                 if (!pFT)
560                 {
561                     SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING);
562                     pFT = pDoc->InsertFldType(aS);
563                 }
564                 SwSetExpField aFld((SwSetExpFieldType*)pFT, pB->GetValSys());
565                 aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE );
566                 MakePoint(pEntry, pDoc, aRegion);
567                 pDoc->InsertPoolItem(aRegion, SwFmtFld(aFld), 0);
568                 MoveAttrs( *(aRegion.GetPoint()) );
569             }
570             if ( ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) &&
571                  !pEntry->bConsumedByField )
572             {
573                 MakeBookRegionOrPoint(pEntry, pDoc, aRegion, sal_True);
574                 // #120879# - create a cross reference heading bookmark if appropriate.
575                 const IDocumentMarkAccess::MarkType eBookmarkType =
576                     ( pB->IsTOCBookmark() &&
577                       IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aRegion ) )
578                     ? IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK
579                     : IDocumentMarkAccess::BOOKMARK;
580                 pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, eBookmarkType );
581             }
582         }
583         break;
584     case RES_FLTR_TOX:
585         {
586             MakePoint(pEntry, pDoc, aRegion);
587 
588             SwPosition* pPoint = aRegion.GetPoint();
589 
590             SwFltTOX* pTOXAttr = (SwFltTOX*)pEntry->pAttr;
591 
592             // test if on this node there had been a pagebreak BEFORE the
593             //     tox attribut was put on the stack
594             SfxItemSet aBkSet( pDoc->GetAttrPool(), RES_PAGEDESC, RES_BREAK );
595             SwCntntNode* pNd = 0;
596             if( !pTOXAttr->HadBreakItem() || !pTOXAttr->HadPageDescItem() )
597             {
598                 pNd = pPoint->nNode.GetNode().GetCntntNode();
599                 if( pNd )
600                 {
601                     const SfxItemSet* pSet = pNd->GetpSwAttrSet();
602                     const SfxPoolItem* pItem;
603                     if( pSet )
604                     {
605                         if(    !pTOXAttr->HadBreakItem()
606                             && SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pItem ) )
607                         {
608                             aBkSet.Put( *pItem );
609                             pNd->ResetAttr( RES_BREAK );
610                         }
611                         if(    !pTOXAttr->HadPageDescItem()
612                             && SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False, &pItem ) )
613                         {
614                             aBkSet.Put( *pItem );
615                             pNd->ResetAttr( RES_PAGEDESC );
616                         }
617                     }
618                 }
619             }
620 
621             delete pTOXAttr->GetBase();
622 
623             // set (aboved saved and removed) the break item at the node following the TOX
624             if( aBkSet.Count() )
625                 pNd->SetAttr( aBkSet );
626         }
627         break;
628     case RES_FLTR_SECTION:
629         MakePoint(pEntry, pDoc, aRegion);   // bislang immer Point==Mark
630         pDoc->InsertSwSection(aRegion,
631                 *(static_cast<SwFltSection*>(pEntry->pAttr))->GetSectionData(),
632                 0, 0, false);
633         delete (((SwFltSection*)pEntry->pAttr)->GetSectionData());
634         break;
635     case RES_FLTR_REDLINE:
636         {
637             if (pEntry->MakeRegion(pDoc, aRegion, sal_True))
638             {
639               pDoc->SetRedlineMode((RedlineMode_t)(   nsRedlineMode_t::REDLINE_ON
640                                               | nsRedlineMode_t::REDLINE_SHOW_INSERT
641                                               | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
642                 SwFltRedline& rFltRedline = *((SwFltRedline*)pEntry->pAttr);
643 
644                 if( USHRT_MAX != rFltRedline.nAutorNoPrev )
645                 {
646                     SwRedlineData aData(rFltRedline.eTypePrev,
647                                         rFltRedline.nAutorNoPrev,
648                                         rFltRedline.aStampPrev,
649                                         aEmptyStr,
650                                         0
651                                         );
652                     pDoc->AppendRedline(new SwRedline(aData, aRegion), true);
653                 }
654                 SwRedlineData aData(rFltRedline.eType,
655                                     rFltRedline.nAutorNo,
656                                     rFltRedline.aStamp,
657                                     aEmptyStr,
658                                     0
659                                     );
660                 pDoc->AppendRedline( new SwRedline(aData, aRegion), true );
661                 pDoc->SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_NONE
662                                                 | nsRedlineMode_t::REDLINE_SHOW_INSERT
663                                                 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
664             }
665         }
666         break;
667     default:
668         {
669             //Modify here for #119405, by chengjh, 2012-08-16
670             //Revised for more complex situations should be considered
671             if ( !bSdODChecked )
672             {
673                 bHasSdOD = HasSdOD();
674                 bSdODChecked = true;
675             }
676                 sal_Int32 nStart = pEntry->GetStartCP();
677                 sal_Int32 nEnd = pEntry->GetEndCP();
678                 if (nStart != -1 && nEnd != -1 && nEnd >= nStart )
679                 {
680                     pEntry->SetIsParaEnd( IsParaEndInCPs(nStart,nEnd,bHasSdOD) );
681                 }
682             //End
683             if (pEntry->MakeRegion(pDoc, aRegion, sal_False))
684             {
685                 //Modify here for #119405, by easyfan, 2012-05-24
686                 //Refined 2012-08-16
687                 if (pEntry->IsParaEnd())
688                 {
689                     pDoc->InsertPoolItem(aRegion, *pEntry->pAttr, 0,true);
690                 }else
691                 {
692                     pDoc->InsertPoolItem(aRegion, *pEntry->pAttr, 0);
693                 }
694                 //End
695             }
696         }
697         break;
698     }
699 }
700 
GetFmtStackAttr(sal_uInt16 nWhich,sal_uInt16 * pPos)701 SfxPoolItem* SwFltControlStack::GetFmtStackAttr(sal_uInt16 nWhich, sal_uInt16 * pPos)
702 {
703     SwFltStackEntry* pEntry;
704     sal_uInt16 nSize = static_cast< sal_uInt16 >(Count());
705 
706     while (nSize)
707     {
708         // ist es das gesuchte Attribut ? (gueltig sind nur gelockte,
709         // also akt. gesetzte Attribute!!)
710         if ((pEntry = (*this)[ --nSize ])->bLocked &&
711             pEntry->pAttr->Which() == nWhich)
712         {
713             if (pPos)
714                 *pPos = nSize;
715             return (SfxPoolItem*)pEntry->pAttr;     // Ok, dann Ende
716         }
717     }
718     return 0;
719 }
720 
GetOpenStackAttr(const SwPosition & rPos,sal_uInt16 nWhich)721 const SfxPoolItem* SwFltControlStack::GetOpenStackAttr(const SwPosition& rPos, sal_uInt16 nWhich)
722 {
723     SwFltStackEntry* pEntry;
724     sal_uInt16 nSize = static_cast< sal_uInt16 >(Count());
725     SwNodeIndex aAktNode( rPos.nNode, -1 );
726     sal_uInt16 nAktIdx = rPos.nContent.GetIndex();
727 
728     while (nSize)
729     {
730         pEntry = (*this)[ --nSize ];
731         if(    pEntry->bLocked
732             && (pEntry->pAttr->Which() == nWhich)
733             && (pEntry->nMkNode  == aAktNode)
734             && (pEntry->nMkCntnt == nAktIdx ))
735         {
736             return (SfxPoolItem*)pEntry->pAttr;
737         }
738     }
739     return 0;
740 }
741 
GetFmtAttr(const SwPosition & rPos,sal_uInt16 nWhich)742 const SfxPoolItem* SwFltControlStack::GetFmtAttr(const SwPosition& rPos, sal_uInt16 nWhich)
743 {
744     SfxPoolItem* pHt = GetFmtStackAttr(nWhich);
745     if (pHt)
746         return (const SfxPoolItem*)pHt;
747 
748     // im Stack ist das Attribut nicht vorhanden, also befrage das Dokument
749 //  SwCntntNode * pNd = rPaM.GetCntntNode();
750     SwCntntNode * pNd = rPos.nNode.GetNode().GetCntntNode();
751 
752     if (!pNd)           // kein ContentNode, dann das dflt. Attribut
753         return &pDoc->GetAttrPool().GetDefaultItem(nWhich);
754     return &pNd->GetAttr(nWhich);
755 }
756 
Delete(const SwPaM & rPam)757 void SwFltControlStack::Delete(const SwPaM &rPam)
758 {
759     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
760 
761     if( !rPam.HasMark() || *pStt >= *pEnd )
762         return;
763 
764     SwNodeIndex aStartNode(pStt->nNode, -1);
765     sal_uInt16 nStartIdx = pStt->nContent.GetIndex();
766     SwNodeIndex aEndNode(pEnd->nNode, -1);
767     sal_uInt16 nEndIdx = pEnd->nContent.GetIndex();
768 
769     //We don't support deleting content that is over one node, or removing a node.
770     ASSERT(aEndNode == aStartNode, "nodes must be the same, or this method extended");
771     if (aEndNode != aStartNode)
772         return;
773 
774     for (sal_uInt16 nSize = static_cast< sal_uInt16 >(Count()); nSize > 0;)
775     {
776         SwFltStackEntry* pEntry = (*this)[--nSize];
777 
778         bool bEntryStartAfterSelStart =
779             (pEntry->nMkNode == aStartNode && pEntry->nMkCntnt >= nStartIdx);
780 
781         bool bEntryStartBeforeSelEnd =
782             (pEntry->nMkNode == aEndNode && pEntry->nMkCntnt <= nEndIdx);
783 
784         bool bEntryEndAfterSelStart = false;
785         bool bEntryEndBeforeSelEnd = false;
786         if (!pEntry->bLocked)
787         {
788             bEntryEndAfterSelStart =
789                 (pEntry->nPtNode == aStartNode && pEntry->nPtCntnt >= nStartIdx);
790 
791             bEntryEndBeforeSelEnd =
792                 (pEntry->nPtNode == aEndNode && pEntry->nPtCntnt <= nEndIdx);
793         }
794 
795         bool bTotallyContained = false;
796         if (
797              bEntryStartAfterSelStart && bEntryStartBeforeSelEnd &&
798              bEntryEndAfterSelStart && bEntryEndBeforeSelEnd
799            )
800         {
801            bTotallyContained = true;
802         }
803 
804         if (bTotallyContained)
805         {
806             //after start, before end, delete
807             DeleteAndDestroy(nSize);
808             continue;
809         }
810 
811         xub_StrLen nCntntDiff = nEndIdx - nStartIdx;
812 
813         //to be adjusted
814         if (bEntryStartAfterSelStart)
815         {
816             if (bEntryStartBeforeSelEnd)
817             {
818                 //move start to new start
819                 pEntry->nMkNode = aStartNode;
820                 pEntry->nMkCntnt = nStartIdx;
821             }
822             else
823                 pEntry->nMkCntnt = pEntry->nMkCntnt - nCntntDiff;
824         }
825 
826         if (bEntryEndAfterSelStart)
827         {
828             if (bEntryEndBeforeSelEnd)
829             {
830                 pEntry->nPtNode = aStartNode;
831                 pEntry->nPtCntnt = nStartIdx;
832             }
833             else
834                 pEntry->nPtCntnt = pEntry->nPtCntnt - nCntntDiff;
835         }
836 
837         //That's what locked is, end equal to start, and nPtCntnt is invalid
838         if (pEntry->bLocked)
839             pEntry->nPtNode = pEntry->nMkNode;
840     }
841 }
842 
843 //------ hier stehen die Methoden von SwFltAnchor -----------
SwFltAnchor(SwFrmFmt * pFmt)844 SwFltAnchor::SwFltAnchor(SwFrmFmt* pFmt) :
845     SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(pFmt)
846 {
847     pClient = new SwFltAnchorClient(this);
848     pFrmFmt->Add(pClient);
849 }
850 
SwFltAnchor(const SwFltAnchor & rCpy)851 SwFltAnchor::SwFltAnchor(const SwFltAnchor& rCpy) :
852     SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(rCpy.pFrmFmt)
853 {
854     pClient = new SwFltAnchorClient(this);
855     pFrmFmt->Add(pClient);
856 }
857 
~SwFltAnchor()858 SwFltAnchor::~SwFltAnchor()
859 {
860     delete pClient;
861 }
862 
SetFrmFmt(SwFrmFmt * _pFrmFmt)863 void SwFltAnchor::SetFrmFmt(SwFrmFmt * _pFrmFmt)
864 {
865     pFrmFmt = _pFrmFmt;
866 }
867 
GetFrmFmt() const868 const SwFrmFmt * SwFltAnchor::GetFrmFmt() const
869 {
870     return pFrmFmt;
871 }
872 
GetFrmFmt()873 SwFrmFmt * SwFltAnchor::GetFrmFmt()
874 {
875     return pFrmFmt;
876 }
877 
operator ==(const SfxPoolItem & rItem) const878 int SwFltAnchor::operator==(const SfxPoolItem& rItem) const
879 {
880     return pFrmFmt == ((SwFltAnchor&)rItem).pFrmFmt;
881 }
882 
Clone(SfxItemPool *) const883 SfxPoolItem* __EXPORT SwFltAnchor::Clone(SfxItemPool*) const
884 {
885     return new SwFltAnchor(*this);
886 }
887 
888 // SwFltAnchorClient
889 
SwFltAnchorClient(SwFltAnchor * pFltAnchor)890 SwFltAnchorClient::SwFltAnchorClient(SwFltAnchor * pFltAnchor)
891 : m_pFltAnchor(pFltAnchor)
892 {
893 }
894 
Modify(const SfxPoolItem *,const SfxPoolItem * pNew)895 void  SwFltAnchorClient::Modify(const SfxPoolItem *, const SfxPoolItem * pNew)
896 {
897     if (pNew->Which() == RES_FMT_CHG)
898     {
899         const SwFmtChg * pFmtChg = dynamic_cast<const SwFmtChg *> (pNew);
900 
901         if (pFmtChg != NULL)
902         {
903             SwFrmFmt * pFrmFmt = dynamic_cast<SwFrmFmt *> (pFmtChg->pChangedFmt);
904 
905             if (pFrmFmt != NULL)
906                 m_pFltAnchor->SetFrmFmt(pFrmFmt);
907         }
908     }
909 }
910 
911 //------ hier stehen die Methoden von SwFltRedline -----------
operator ==(const SfxPoolItem & rItem) const912 int SwFltRedline::operator==(const SfxPoolItem& rItem) const
913 {
914     return this == &rItem;
915 }
916 
Clone(SfxItemPool *) const917 SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const
918 {
919     return new SwFltRedline(*this);
920 }
921 
922 //------ hier stehen die Methoden von SwFltBookmark -----------
SwFltBookmark(const String & rNa,const String & rVa,long nHand,const bool bIsTOCBookmark)923 SwFltBookmark::SwFltBookmark( const String& rNa, const String& rVa,
924                               long nHand, const bool bIsTOCBookmark )
925     : SfxPoolItem( RES_FLTR_BOOKMARK )
926     , mnHandle( nHand )
927     , maName( rNa )
928     , maVal( rVa )
929     , mbIsTOCBookmark( bIsTOCBookmark )
930 {
931     // eSrc: CHARSET_DONTKNOW fuer keine UEbersetzung bei operator <<
932     // Upcase wird immer gemacht.
933     // bei XXXStack.NewAttr(...) wird nie eine UEbersetzung vorgenommen.
934     // ansonsten: uebergebener Src-Charset fuer aName
935     // im Filter eingestellter Src-Charset fuer aVal ( Text )
936 
937     if ( IsTOCBookmark() )
938     {
939         maName = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix();
940         maName += rNa;
941     }
942 }
943 
SwFltBookmark(const SwFltBookmark & rCpy)944 SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy)
945     : SfxPoolItem( RES_FLTR_BOOKMARK )
946     , mnHandle( rCpy.mnHandle )
947     , maName( rCpy.maName )
948     , maVal( rCpy.maVal )
949     , mbIsTOCBookmark( rCpy.mbIsTOCBookmark )
950 {
951 }
952 
operator ==(const SfxPoolItem & rItem) const953 int SwFltBookmark::operator==(const SfxPoolItem& rItem) const
954 {
955     return ( maName == ((SwFltBookmark&)rItem).maName)
956             && (mnHandle == ((SwFltBookmark&)rItem).mnHandle);
957 }
958 
Clone(SfxItemPool *) const959 SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const
960 {
961     return new SwFltBookmark(*this);
962 }
963 
964 //------ hier stehen die Methoden von SwFltTOX -----------
965 
SwFltTOX(SwTOXBase * pBase,sal_uInt16 _nCols)966 SwFltTOX::SwFltTOX(SwTOXBase* pBase, sal_uInt16 _nCols)
967     : SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ),
968       bHadBreakItem( sal_False ), bHadPageDescItem( sal_False )
969 {
970 }
971 
SwFltTOX(const SwFltTOX & rCpy)972 SwFltTOX::SwFltTOX(const SwFltTOX& rCpy)
973     : SfxPoolItem(RES_FLTR_TOX), pTOXBase(rCpy.pTOXBase), nCols( rCpy.nCols ),
974       bHadBreakItem( rCpy.bHadBreakItem ), bHadPageDescItem( rCpy.bHadPageDescItem )
975 {
976 }
977 
operator ==(const SfxPoolItem & rItem) const978 int SwFltTOX::operator==(const SfxPoolItem& rItem) const
979 {
980     return pTOXBase == ((SwFltTOX&)rItem).pTOXBase;
981 }
982 
Clone(SfxItemPool *) const983 SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const
984 {
985     return new SwFltTOX(*this);
986 }
987 
988 //------ hier stehen die Methoden von SwFltSwSection -----------
989 
SwFltSection(SwSectionData * const pSect)990 SwFltSection::SwFltSection(SwSectionData *const pSect)
991     : SfxPoolItem(RES_FLTR_SECTION)
992     , m_pSection(pSect)
993 {
994 }
995 
SwFltSection(const SwFltSection & rCpy)996 SwFltSection::SwFltSection(const SwFltSection& rCpy)
997     : SfxPoolItem(RES_FLTR_SECTION)
998     , m_pSection(rCpy.m_pSection)
999 {
1000 }
1001 
operator ==(const SfxPoolItem & rItem) const1002 int SwFltSection::operator==(const SfxPoolItem& rItem) const
1003 {
1004     return m_pSection == ((SwFltSection&)rItem).m_pSection;
1005 }
1006 
Clone(SfxItemPool *) const1007 SfxPoolItem* __EXPORT SwFltSection::Clone(SfxItemPool*) const
1008 {
1009     return new SwFltSection(*this);
1010 }
1011 
1012 ///////////////////////////////////////////////////////////////////////
1013 //
1014 // hier beginnt der von mdt erzeugte code. dieser ist eine shell auf
1015 // der writer-seite nach moeglichkeit bald fuer alle filter. die ganze
1016 // schwierigkeit, texte & formatattribute einzufuegen, die positionen
1017 // zu verwalten, styles & kopf/fuszzeilen etc.
1018 //
1019 
1020 //////////////////////////////////////////////////////////// SwFltShell
SwFltShell(SwDoc * pDoc,SwPaM & rPaM,const String & rBaseURL,sal_Bool bNew,sal_uLong nFieldFl)1021 SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const String& rBaseURL, sal_Bool bNew, sal_uLong nFieldFl) :
1022     pCurrentPageDesc(0),
1023     pSavedPos(0),
1024     eSubMode(None),
1025     nAktStyle(0),
1026     aStack(pDoc, nFieldFl),
1027     aEndStack(pDoc, nFieldFl),
1028     pPaM(new SwPaM(*(rPaM.GetPoint()))),
1029     sBaseURL(rBaseURL),
1030     nPageDescOffset(GetDoc().GetPageDescCnt()),
1031     eSrcCharSet(RTL_TEXTENCODING_MS_1252),
1032     bNewDoc(bNew),
1033     bStdPD(sal_False),
1034     bProtect(sal_False)
1035 {
1036     memset( pColls, 0, sizeof( pColls ) );
1037     pOutDoc = new SwFltOutDoc( *pDoc, pPaM, aStack, aEndStack );
1038     pOut = pOutDoc;
1039 
1040     if( !bNewDoc ){     // in ein Dokument einfuegen ?
1041                         // Da immer ganze Zeile eingelesen werden, muessen
1042                         // evtl. Zeilen eingefuegt / aufgebrochen werden
1043         const SwPosition* pPos = pPaM->GetPoint();
1044         const SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode();
1045         sal_uInt16 nCntPos = pPos->nContent.GetIndex();
1046         if( nCntPos && pSttNd->GetTxt().Len() )
1047                                             // EinfuegePos nicht in leerer Zeile
1048             pDoc->SplitNode( *pPos, false );        // neue Zeile erzeugen
1049         if( pSttNd->GetTxt().Len() ){       // EinfuegePos nicht am Ende der Zeile
1050             pDoc->SplitNode( *pPos, false );        // neue Zeile
1051             pPaM->Move( fnMoveBackward );   // gehe in leere Zeile
1052         }
1053 
1054         // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen
1055         sal_uLong nNd = pPos->nNode.GetIndex();
1056         sal_Bool bReadNoTbl = 0 != pSttNd->FindTableNode() ||
1057             ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() &&
1058             pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
1059         if( bReadNoTbl )
1060             pOutDoc->SetReadNoTable();
1061     }
1062     pCurrentPageDesc =  &((SwPageDesc&)const_cast<const SwDoc *>(pDoc)
1063                           ->GetPageDesc( 0 ));  // Standard
1064 
1065 }
1066 
~SwFltShell()1067 SwFltShell::~SwFltShell()
1068 {
1069     sal_uInt16 i;
1070 
1071     if (eSubMode == Style)
1072         EndStyle();
1073     if( pOutDoc->IsInTable() )          // falls nicht ordentlich abgeschlossen
1074         EndTable();
1075     if( pOutDoc->IsInFly() )
1076         EndFly();
1077 
1078     GetDoc().SetUpdateExpFldStat(true);
1079     GetDoc().SetInitDBFields(sal_True);
1080     aStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1081     aStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1082     aEndStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1083     aEndStack.SetAttr(*pPaM->GetPoint(), 0, sal_False);
1084     if( bProtect ){     // Das ganze Doc soll geschuetzt sein
1085 
1086         SwDoc& rDoc = GetDoc();
1087                         // 1. SectionFmt und Section anlegen
1088         SwSectionFmt* pSFmt = rDoc.MakeSectionFmt( 0 );
1089         SwSectionData aSectionData( CONTENT_SECTION, String::CreateFromAscii(
1090                                 RTL_CONSTASCII_STRINGPARAM("PMW-Protect") ));
1091         aSectionData.SetProtectFlag( true );
1092                         // 2. Start- und EndIdx suchen
1093         const SwNode* pEndNd = &rDoc.GetNodes().GetEndOfContent();
1094         SwNodeIndex aEndIdx( *pEndNd, -1L );
1095         const SwStartNode* pSttNd = pEndNd->StartOfSectionNode();
1096         SwNodeIndex aSttIdx( *pSttNd, 1L );         // +1 -> hinter StartNode
1097                                                     // Section einfuegen
1098                         // Section einfuegen
1099         rDoc.GetNodes().InsertTextSection(
1100                 aSttIdx, *pSFmt, aSectionData, 0, &aEndIdx, false );
1101 
1102         if( !IsFlagSet(SwFltControlStack::DONT_HARD_PROTECT) ){
1103             SwDocShell* pDocSh = rDoc.GetDocShell();
1104             if( pDocSh )
1105                 pDocSh->SetReadOnlyUI( sal_True );
1106         }
1107     }
1108         // Pagedescriptoren am Dokument updaten (nur so werden auch die
1109         // linken Seiten usw. eingestellt).
1110 
1111     GetDoc().ChgPageDesc( 0,
1112                           const_cast<const SwDoc &>(GetDoc()).
1113                           GetPageDesc( 0 ));    // PageDesc "Standard"
1114     for (i=nPageDescOffset;i<GetDoc().GetPageDescCnt();i++)
1115     {
1116         const SwPageDesc& rPD = const_cast<const SwDoc &>(GetDoc()).
1117             GetPageDesc(i);
1118         GetDoc().ChgPageDesc(i, rPD);
1119     }
1120 
1121     delete pPaM;
1122     for (i=0; i<sizeof(pColls)/sizeof(*pColls); i++)
1123         if( pColls[i] )
1124             delete pColls[i];
1125     delete pOutDoc;
1126 }
1127 
operator <<(const String & rStr)1128 SwFltShell& SwFltShell::operator << ( const String& rStr )
1129 {
1130     ASSERT(eSubMode != Style, "char insert while in style-mode");
1131     GetDoc().InsertString( *pPaM, rStr );
1132     return *this;
1133 }
1134 
ConvertUStr(String & rInOut)1135 void SwFltShell::ConvertUStr( String& rInOut )
1136 {
1137     GetAppCharClass().toUpper( rInOut );
1138 }
1139 
1140 // QuoteString() wandelt CRs abhaengig von nFieldIniFlags in '\n' oder "\0x0d"
QuoteStr(const String & rIn)1141 String SwFltShell::QuoteStr( const String& rIn )
1142 {
1143     String sOut( rIn );
1144     sal_Bool bAllowCr = aStack.IsFlagSet( SwFltControlStack::ALLOW_FLD_CR );
1145 
1146     for( xub_StrLen n = 0; n < sOut.Len(); ++n )
1147     {
1148         switch( sOut.GetChar( n ) )
1149         {
1150         case 0x0a:
1151             sOut.Erase( n, 1 );             // 0xd 0xa wird zu \n
1152             break;
1153 
1154         case 0x0b:
1155         case 0x0c:
1156         case 0x0d:
1157             if( bAllowCr )
1158                 sOut.SetChar( n, '\n' );
1159             break;
1160         }
1161     }
1162     return sOut;
1163 }
1164 
operator <<(const sal_Unicode c)1165 SwFltShell& SwFltShell::operator << ( const sal_Unicode c )
1166 {
1167     ASSERT( eSubMode != Style, "char insert while in style-mode");
1168     GetDoc().InsertString( *pPaM, c );
1169     return *this;
1170 }
1171 
AddError(const sal_Char * pErr)1172 SwFltShell& SwFltShell::AddError( const sal_Char* pErr )
1173 {
1174     String aName( String::CreateFromAscii(
1175                     RTL_CONSTASCII_STRINGPARAM( "ErrorTag" )));
1176     SwFieldType* pFT = GetDoc().GetFldType( RES_SETEXPFLD, aName, false );
1177     if( pFT == 0)
1178     {
1179         SwSetExpFieldType aS(&GetDoc(), aName, nsSwGetSetExpType::GSE_STRING);
1180         pFT = GetDoc().InsertFldType(aS);
1181     }
1182     SwSetExpField aFld( (SwSetExpFieldType*)pFT,
1183                         String::CreateFromAscii( pErr ));
1184     //, VVF_INVISIBLE
1185     GetDoc().InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
1186     return *this;
1187 }
1188 
operator <<(Graphic & rGraphic)1189 SwFltShell& SwFltShell::operator << (Graphic& rGraphic)
1190 {
1191     // embedded Grafik !!
1192     GetDoc().Insert(*pPaM, aEmptyStr, aEmptyStr, &rGraphic, NULL, NULL, NULL);
1193     return *this;
1194 }
1195 
NextParagraph()1196 void SwFltShell::NextParagraph()
1197 {
1198     GetDoc().AppendTxtNode(*pPaM->GetPoint());
1199 }
1200 
NextPage()1201 void SwFltShell::NextPage()
1202 {
1203     NextParagraph();
1204     GetDoc().InsertPoolItem(*pPaM,
1205         SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0);
1206 }
1207 
AddGraphic(const String & rPicName)1208 SwFltShell& SwFltShell::AddGraphic( const String& rPicName )
1209 {
1210     // embedded:
1211     GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter();
1212     Graphic aGraphic;
1213     // one of: GFF_NOT GFF_BMP GFF_GIF GFF_JPG GFF_PCD GFF_PCX GFF_PNG
1214     // GFF_TIF GFF_XBM GFF_DXF GFF_MET GFF_PCT GFF_SGF GFF_SVM GFF_WMF
1215     // GFF_SGV GFF_XXX
1216     INetURLObject aDir(
1217         URIHelper::SmartRel2Abs(
1218             INetURLObject(GetBaseURL()), rPicName,
1219             URIHelper::GetMaybeFileHdl()) );
1220     switch (pFilter->ImportGraphic(aGraphic, aDir))
1221     {
1222         case GRFILTER_OK:
1223             *this << aGraphic;
1224             break;
1225         case GRFILTER_OPENERROR:
1226         case GRFILTER_IOERROR:
1227         case GRFILTER_FORMATERROR:
1228         case GRFILTER_VERSIONERROR:
1229         case GRFILTER_FILTERERROR:
1230         case GRFILTER_ABORT:
1231         case GRFILTER_TOOBIG:
1232         default:
1233             AddError( "picture import error" );
1234             break;
1235     }
1236     return *this;
1237 }
1238 
SetStyle(sal_uInt16 nStyle)1239 SwFltShell& SwFltShell::SetStyle( sal_uInt16 nStyle )
1240 {
1241     SwFltFormatCollection* p = pColls[ nStyle ];
1242 
1243     if (p)
1244     {
1245         if( !pOutDoc->IsInTable() && nStyle != nAktStyle )
1246         {
1247             if( pColls[nAktStyle]->IsInFly() && pOutDoc->IsInFly() )
1248                 pOutDoc->EndFly();
1249             if( p->IsInFly() )
1250                 p->BeginStyleFly( pOutDoc );
1251         }
1252         GetDoc().SetTxtFmtColl(*pPaM, p->GetColl());
1253         nAktStyle = nStyle;
1254     }
1255     else
1256     {
1257         ASSERT( sal_False, "Ungueltiger SwFltStyleCode" );
1258     }
1259     return *this;
1260 }
1261 
operator <<(SwFltBookmark & aBook)1262 SwFltShell& SwFltShell::operator << (SwFltBookmark& aBook)
1263 {
1264     ConvertUStr( aBook.maName );
1265     aBook.maVal = QuoteStr(aBook.maVal);
1266     aEndStack.NewAttr(*pPaM->GetPoint(), aBook);
1267     return *this;
1268 }
1269 
SetBookEnd(long nHandle)1270 void SwFltShell::SetBookEnd(long nHandle)
1271 {
1272     aEndStack.SetAttr( *pPaM->GetPoint(), RES_FLTR_BOOKMARK, sal_True, nHandle );
1273 }
1274 
EndItem(sal_uInt16 nAttrId)1275 SwFltShell& SwFltShell::EndItem( sal_uInt16 nAttrId )
1276 {
1277     switch( nAttrId )
1278     {
1279     case RES_FLTR_BOOKMARK:
1280         ASSERT( sal_False, "Falscher Aufruf fuer Bookmark-Ende" );
1281         break;
1282 
1283     case RES_FLTR_TOX:
1284         aEndStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1285         break;
1286 
1287     default:
1288         aStack.SetAttr(*pPaM->GetPoint(), nAttrId);
1289         break;
1290     }
1291     return *this;
1292 }
1293 
operator <<(const SwField & rField)1294 SwFltShell& SwFltShell::operator << (const SwField& rField)
1295 {
1296     GetDoc().InsertPoolItem(*pPaM, SwFmtFld(rField), 0);
1297     return *this;
1298 }
1299 
operator <<(const SfxPoolItem & rItem)1300 /*virtual*/ SwFltOutBase& SwFltOutDoc::operator << (const SfxPoolItem& rItem)
1301 {
1302     rStack.NewAttr(*pPaM->GetPoint(), rItem);
1303     return *this;
1304 }
1305 
operator <<(const SfxPoolItem & rItem)1306 /*virtual*/ SwFltOutBase& SwFltFormatCollection::operator <<
1307                                 (const SfxPoolItem& rItem)
1308 {
1309     pColl->SetFmtAttr(rItem);
1310     return *this;
1311 }
1312 
GetAttr(sal_uInt16 nWhich)1313 const SfxPoolItem& SwFltOutDoc::GetAttr(sal_uInt16 nWhich)
1314 {
1315     return *rStack.GetFmtAttr(*pPaM->GetPoint(), nWhich);
1316 }
1317 
GetAttr(sal_uInt16 nWhich)1318 const SfxPoolItem& SwFltFormatCollection::GetAttr(sal_uInt16 nWhich)
1319 {
1320     return GetColl()->GetFmtAttr(nWhich);   // mit Parents
1321 }
1322 
1323 // GetNodeOrStyAttr holt Attribute fuer Toggle- und Modify-Attribute:
1324 // Bei Formatdefinitionen aus dem altuellen Style mit Parents
1325 // sonst aus dem Node mit Parents
1326 // Im Stack wird nicht nachgesehen
1327 
GetNodeOrStyAttr(sal_uInt16 nWhich)1328 const SfxPoolItem& SwFltOutDoc::GetNodeOrStyAttr(sal_uInt16 nWhich)
1329 {
1330     SwCntntNode * pNd = pPaM->GetPoint()->nNode.GetNode().GetCntntNode();
1331     if (pNd)            // ContentNode: Attribut mit Parent
1332         return pNd->GetAttr(nWhich);
1333     else                // kein ContentNode, dann das dflt. Attribut
1334         return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1335 }
1336 
GetNodeOrStyAttr(sal_uInt16 nWhich)1337 const SfxPoolItem& SwFltFormatCollection::GetNodeOrStyAttr(sal_uInt16 nWhich)
1338 {
1339     return GetColl()->GetFmtAttr(nWhich);   // mit Parents
1340 }
1341 
GetNodeOrStyAttr(sal_uInt16 nWhich)1342 const SfxPoolItem& SwFltShell::GetNodeOrStyAttr(sal_uInt16 nWhich)
1343 {
1344     return pOut->GetNodeOrStyAttr( nWhich );
1345 }
1346 
GetAttr(sal_uInt16 nWhich)1347 const SfxPoolItem& SwFltShell::GetAttr(sal_uInt16 nWhich)
1348 {
1349     return pOut->GetAttr( nWhich );
1350 }
1351 
GetFlyFrmAttr(sal_uInt16 nWhich)1352 const SfxPoolItem& SwFltShell::GetFlyFrmAttr(sal_uInt16 nWhich)
1353 {
1354     return pOut->GetFlyFrmAttr( nWhich );
1355 }
1356 
GetSysFldType(sal_uInt16 eWhich)1357 SwFieldType* SwFltShell::GetSysFldType(sal_uInt16 eWhich)
1358 {
1359     return GetDoc().GetSysFldType(eWhich);
1360 }
1361 
GetWeightBold()1362 sal_Bool SwFltShell::GetWeightBold()
1363 {
1364     return ((SvxWeightItem&)GetNodeOrStyAttr(RES_CHRATR_WEIGHT)).GetWeight()
1365                                 != WEIGHT_NORMAL;
1366 }
1367 
GetPostureItalic()1368 sal_Bool SwFltShell::GetPostureItalic()
1369 {
1370     return ((SvxPostureItem&)GetNodeOrStyAttr(RES_CHRATR_POSTURE)).GetPosture()
1371                                 != ITALIC_NONE;
1372 }
1373 
GetCrossedOut()1374 sal_Bool SwFltShell::GetCrossedOut()
1375 {
1376     return ((SvxCrossedOutItem&)GetNodeOrStyAttr(RES_CHRATR_CROSSEDOUT))
1377                                     .GetStrikeout() != STRIKEOUT_NONE;
1378 }
1379 
GetContour()1380 sal_Bool SwFltShell::GetContour()
1381 {
1382     return ((SvxContourItem&)GetNodeOrStyAttr(RES_CHRATR_CONTOUR)).GetValue();
1383 }
1384 
GetCaseKapitaelchen()1385 sal_Bool SwFltShell::GetCaseKapitaelchen()
1386 {
1387     return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1388                                     .GetCaseMap() == SVX_CASEMAP_KAPITAELCHEN;
1389 }
1390 
GetCaseVersalien()1391 sal_Bool SwFltShell::GetCaseVersalien()
1392 {
1393     return ((SvxCaseMapItem&)GetNodeOrStyAttr(RES_CHRATR_CASEMAP))
1394                                     .GetCaseMap() == SVX_CASEMAP_VERSALIEN;
1395 }
1396 
1397 //-------------------------------------------------------------------------
1398 // Tabellen
1399 //-------------------------------------------------------------------------
1400 
~SwFltOutBase()1401 SwFltOutBase::~SwFltOutBase()
1402 {
1403 }
1404 
SwFltOutBase(SwDoc & rDocu)1405 SwFltOutBase::SwFltOutBase(SwDoc& rDocu)
1406     : rDoc(rDocu), eFlyAnchor(FLY_AT_PARA), bFlyAbsPos(false)
1407 {
1408 }
1409 
GetCellAttr(sal_uInt16 nWhich)1410 const SfxPoolItem& SwFltOutBase::GetCellAttr(sal_uInt16 nWhich)
1411 {
1412     ASSERT(sal_False, "GetCellAttr ausserhalb von normalem Text");
1413     return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1414 }
1415 
BeginTable()1416 sal_Bool SwFltOutBase::BeginTable()
1417 {
1418     ASSERT(sal_False, "BeginTable ausserhalb von normalem Text");
1419     return sal_False;
1420 }
1421 
NextTableCell()1422 void SwFltOutBase::NextTableCell()
1423 {
1424     ASSERT(sal_False, "NextTableCell ausserhalb von normalem Text");
1425 }
1426 
NextTableRow()1427 void SwFltOutBase::NextTableRow()
1428 {
1429     ASSERT(sal_False, "NextTableRow ausserhalb von normalem Text");
1430 }
1431 
SetTableWidth(SwTwips)1432 void SwFltOutBase::SetTableWidth(SwTwips /*nW*/)
1433 {
1434     ASSERT(sal_False, "SetTableWidth ausserhalb von normalem Text");
1435 }
1436 
SetTableOrient(sal_Int16)1437 void SwFltOutBase::SetTableOrient(sal_Int16 /*eOri*/)
1438 {
1439     ASSERT(sal_False, "SetTableOrient ausserhalb von normalem Text");
1440 }
1441 
SetCellWidth(SwTwips,sal_uInt16)1442 void SwFltOutBase::SetCellWidth(SwTwips /*nWidth*/, sal_uInt16 /*nCell*/)
1443 {
1444     ASSERT(sal_False, "SetCellWidth ausserhalb von normalem Text");
1445 }
1446 
SetCellHeight(SwTwips)1447 void SwFltOutBase::SetCellHeight(SwTwips /*nH*/)
1448 {
1449     ASSERT(sal_False, "SetCellHeight ausserhalb von normalem Text");
1450 }
1451 
SetCellBorder(const SvxBoxItem &,sal_uInt16)1452 void SwFltOutBase::SetCellBorder(const SvxBoxItem& /*rFmtBox*/, sal_uInt16 /*nCell*/)
1453 {
1454     ASSERT(sal_False, "SetCellBorder ausserhalb von normalem Text");
1455 }
1456 
SetCellSpace(sal_uInt16)1457 void SwFltOutBase::SetCellSpace(sal_uInt16 /*nSp*/)
1458 {
1459     ASSERT(sal_False, "SetCellSpace ausserhalb von normalem Text");
1460 }
1461 
DeleteCell(sal_uInt16)1462 void SwFltOutBase::DeleteCell(sal_uInt16 /*nCell*/)
1463 {
1464     ASSERT(sal_False, "DeleteCell ausserhalb von normalem Text");
1465 }
1466 
EndTable()1467 void SwFltOutBase::EndTable()
1468 {
1469     ASSERT(sal_False, "EndTable ausserhalb von normalem Text");
1470 }
1471 
IsInTable()1472 /*virtual*/ sal_Bool SwFltOutDoc::IsInTable()
1473 {
1474     return pTable != 0;
1475 };
1476 
BeginTable()1477 sal_Bool SwFltOutDoc::BeginTable()
1478 {
1479     if(bReadNoTbl)
1480         return sal_False;
1481 
1482     if (pTable){
1483         ASSERT(sal_False, "BeginTable in Table");
1484         return sal_False;
1485     }
1486                             // Alle Attribute schliessen, da sonst Attribute
1487                             // entstehen koennen, die in Flys reinragen
1488     rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1489     rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1490 
1491 // create table:
1492     ASSERT(pTabSavedPos == NULL, "SwFltOutDoc");
1493     pTabSavedPos = new SwPosition(*pPaM->GetPoint());
1494     pTable = GetDoc().InsertTable(
1495             SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
1496             *pTabSavedPos, 1, 1, text::HoriOrientation::LEFT, 0, 0, sal_False, sal_False ); // TODO MULTIHEADER
1497     nTableWidth = 0;
1498     ((SwTable*)pTable)->LockModify();   // Nichts automatisch anpassen!
1499 // set pam in 1. table cell
1500     usTableX =
1501     usTableY = 0;
1502     SeekCell(usTableY, usTableX, sal_True);
1503     return sal_True;
1504 }
1505 
GetBox(sal_uInt16 ny,sal_uInt16 nx)1506 SwTableBox* SwFltOutDoc::GetBox(sal_uInt16 ny, sal_uInt16 nx /*= USHRT_MAX */)
1507 {
1508     if(!pTable){
1509         ASSERT(pTable, "GetBox ohne Tabelle");
1510         return 0;
1511     }
1512     if( nx == USHRT_MAX )   // aktuelle Zelle
1513         nx = usTableX;
1514 
1515 // get structs to table cells
1516     const SwTableLines* pTableLines = &pTable->GetTabLines();
1517     if(!pTableLines){
1518         ASSERT(sal_False, "SwFltOutDoc:GetBox:pTableLines");
1519         return 0;
1520     }
1521     if( ny >= pTableLines->Count() ){   // Notbremse
1522         ASSERT( sal_False, "SwFltOutDoc:GetBox:ny >= Count()");
1523         ny = pTableLines->Count() - 1;
1524     }
1525     SwTableLine* pTableLine = (*pTableLines)[ny];
1526     if(!pTableLine){
1527         ASSERT(sal_False, "SwFltOutDoc:GetBox:pTableLine");
1528         return 0;
1529     }
1530     SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1531     if(!pTableBoxes){
1532         ASSERT(sal_False, "SwFltOutDoc:GetBox:pTableBoxes");
1533         return 0;
1534     }
1535     if( nx >= pTableBoxes->Count() ){   // Notbremse
1536         ASSERT(sal_False, "SwFltOutDoc:GetBox:nx >= Count()");
1537         nx = pTableBoxes->Count() - 1;
1538     }
1539     SwTableBox* pTableBox = (*pTableBoxes)[nx];
1540 
1541     ASSERT(pTableBox != 0, "SwFltOutDoc:GetBox:pTableBox");
1542     return pTableBox;
1543 }
1544 
NextTableCell()1545 void SwFltOutDoc::NextTableCell()
1546 {
1547     if(!pTable){
1548         ASSERT(pTable, "NextTableCell ohne Tabelle");
1549         return;
1550     }
1551     const SwTableLines* pTableLines = &pTable->GetTabLines();
1552     SwTableLine* pTableLine = (*pTableLines)[usTableY];
1553     SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1554     SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1555     ASSERT(pTableBox != 0, "SwFltOutDoc:NextTableCell:pTableBox");
1556     if(!pTableBox)
1557         return;
1558 //#pragma message(__FILE__ "(?) : Sw's const problem")
1559 // insert cells:
1560     if (++usTableX >= pTableBoxes->Count())
1561         GetDoc().GetNodes().InsBoxen(
1562          GetDoc().IsIdxInTbl(pPaM->GetPoint()->nNode),
1563          pTableLine,
1564          (SwTableBoxFmt*)pTableBox->GetFrmFmt(),
1565          GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ),
1566          0,
1567          pTableBoxes->Count());
1568     SeekCell(usTableY, usTableX, sal_True);
1569     pTableBox = (*pTableBoxes)[usTableX];
1570     ASSERT(pTableBox != 0, "SwFltOutDoc:pTableBox");
1571     if(pTableBox)
1572         (*pTableBoxes)[usTableX]->ClaimFrmFmt();
1573 }
1574 
NextTableRow()1575 void SwFltOutDoc::NextTableRow()
1576 {
1577     SwTableBox* pTableBox = GetBox(usTableY, 0);
1578     if (pTableBox)
1579     {
1580 // duplicate row:
1581         SwSelBoxes aSelBoxes;
1582         aSelBoxes.Insert( pTableBox );
1583         GetDoc().InsertRow(aSelBoxes);
1584         usTableX = 0;
1585         SeekCell(++usTableY, usTableX, sal_True);
1586         GetDoc().SetTxtFmtColl(*pPaM,
1587             GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1588     }
1589 }
1590 
SetTableWidth(SwTwips nSwWidth)1591 void SwFltOutDoc::SetTableWidth(SwTwips nSwWidth)
1592 {
1593     if(!pTable){
1594         ASSERT(pTable, "SetTableWidth ohne Tabelle");
1595         return;
1596     }
1597     ASSERT( nSwWidth > MINLAY, "Tabellenbreite <= MINLAY" );
1598     if( nSwWidth != nTableWidth ){
1599         if( nTableWidth )           // Nicht beim ersten Setzen
1600             SplitTable();
1601         pTable->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize(ATT_VAR_SIZE, nSwWidth));
1602         nTableWidth = nSwWidth;
1603     }
1604 }
1605 
SetTableOrient(sal_Int16 eOri)1606 void SwFltOutDoc::SetTableOrient(sal_Int16 eOri)
1607 {
1608     if(!pTable){
1609         ASSERT(pTable, "SetTableOrient ohne Tabelle");
1610         return;
1611     }
1612     pTable->GetFrmFmt()->SetFmtAttr( SwFmtHoriOrient( 0, eOri ));
1613 }
1614 
SetCellWidth(SwTwips nWidth,sal_uInt16 nCell)1615 void SwFltOutDoc::SetCellWidth(SwTwips nWidth, sal_uInt16 nCell /* = USHRT_MAX */ )
1616 {
1617     if(!pTable){
1618         ASSERT(pTable, "SetCellWidth ohne Tabelle");
1619         return;
1620     }
1621     ASSERT( nWidth > MINLAY, "Tabellenzellenbreite <= MINLAY" );
1622     if (nWidth < MINLAY)
1623         nWidth = MINLAY;
1624 
1625     SwTableBox* pTableBox = GetBox(usTableY, nCell);
1626     if(pTableBox && pTableBox->GetFrmFmt() ){
1627         SwFmtFrmSize aFmtFrmSize(ATT_FIX_SIZE);
1628         aFmtFrmSize.SetWidth(nWidth);
1629         pTableBox->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1630     }
1631 }
1632 
SetCellHeight(SwTwips nHeight)1633 void SwFltOutDoc::SetCellHeight(SwTwips nHeight)
1634 {
1635     if(!pTable){
1636         ASSERT(pTable, "SetCellHeight ohne Tabelle");
1637         return;
1638     }
1639 
1640     const SwTableLines* pTableLines = &pTable->GetTabLines();
1641     SwTableLine* pTableLine = (*pTableLines)[usTableY];
1642     SwFmtFrmSize aFmtFrmSize(ATT_MIN_SIZE, 0, 0);
1643     if (nHeight < MINLAY)
1644         nHeight = MINLAY;
1645     aFmtFrmSize.SetHeight(nHeight);
1646     pTableLine->GetFrmFmt()->SetFmtAttr(aFmtFrmSize);
1647 }
1648 
GetCellAttr(sal_uInt16 nWhich)1649 const SfxPoolItem& SwFltOutDoc::GetCellAttr(sal_uInt16 nWhich)
1650 {
1651     if (!pTable){
1652         ASSERT(pTable, "GetCellAttr ohne Table");
1653         return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1654     }
1655 
1656     SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1657     if(!pTableBox)
1658         return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1659     return pTableBox->GetFrmFmt()->GetFmtAttr( nWhich );
1660 }
1661 
SetCellBorder(const SvxBoxItem & rFmtBox,sal_uInt16 nCell)1662 void SwFltOutDoc::SetCellBorder(const SvxBoxItem& rFmtBox,
1663                                sal_uInt16 nCell /* = USHRT_MAX */ )
1664 {
1665     SwTableBox* pTableBox = GetBox(usTableY, nCell);
1666     if(pTableBox)
1667         pTableBox->GetFrmFmt()->SetFmtAttr(rFmtBox);
1668 }
1669 
1670 // nicht aktiviert !!!
SetCellSpace(sal_uInt16 nDist)1671 void SwFltOutDoc::SetCellSpace(sal_uInt16 nDist)
1672 {
1673     if(!pTable){
1674         ASSERT(pTable, "SetCellSpace ohne Tabelle");
1675         return;
1676     }
1677     SwTableBox* pTableBox = GetBox(usTableY, usTableX);
1678     if(!pTableBox)
1679         return;
1680 
1681     SvxBoxItem aFmtBox( *((SvxBoxItem*)
1682                         &pTableBox->GetFrmFmt()->GetFmtAttr( RES_BOX )));
1683 
1684     // versteh ich nich, sven: if (!nDist) nDist = 18; // ca. 0.03 cm
1685     if (nDist > 42) // max. 0.7 mm
1686         nDist = 42;
1687     else
1688         if (nDist < MIN_BORDER_DIST)
1689             nDist = MIN_BORDER_DIST;
1690     aFmtBox.SetDistance(nDist);
1691     pTableBox->GetFrmFmt()->SetFmtAttr(aFmtBox);
1692 }
1693 
DeleteCell(sal_uInt16 nCell)1694 void SwFltOutDoc::DeleteCell(sal_uInt16 nCell /* = USHRT_MAX */)
1695 {
1696     SwTableBox* pTableBox = GetBox(usTableY, nCell);
1697     if(pTableBox){
1698         SwSelBoxes aSelBoxes;
1699         aSelBoxes.Insert( pTableBox );
1700         GetDoc().DeleteRowCol(aSelBoxes);
1701         usTableX--;
1702     }
1703 }
1704 
SplitTable()1705 void SwFltOutDoc::SplitTable()
1706 {
1707     if(!pTable)
1708     {
1709         ASSERT(pTable, "SplitTable ohne Tabelle");
1710         return;
1711     }
1712     SwTableBox* pAktBox = GetBox(usTableY, usTableX);
1713     SwTableBox* pSplitBox = GetBox(usTableY - 1, 0);
1714     GetDoc().GetNodes().SplitTable(SwNodeIndex(*pSplitBox->GetSttNd()), false);
1715     pTable = &pAktBox->GetSttNd()->FindTableNode()->GetTable();
1716     usTableY = 0;
1717 }
1718 
EndTable()1719 void SwFltOutDoc::EndTable()
1720 {
1721     if (!pTable){
1722         ASSERT(pTable, "EndTable ohne Table");
1723         return;
1724     }
1725                             // Alle Attribute schliessen, da sonst Attribute
1726                             // entstehen koennen, die in Flys reinragen
1727     rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1728     rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1729 
1730     if (GetDoc().GetCurrentViewShell()){    //swmod 071108//swmod 071225
1731         SwTableNode* pTableNode = GetDoc().IsIdxInTbl(
1732             pPaM->GetPoint()->nNode);
1733         pTableNode->DelFrms();
1734         pTableNode->MakeFrms(&pPaM->GetPoint()->nNode);
1735     }
1736 
1737     *pPaM->GetPoint() = *pTabSavedPos;              // restore Cursor
1738     delete pTabSavedPos;
1739     pTabSavedPos = 0;
1740     ((SwTable*)pTable)->UnlockModify(); // Test, nuetzt nichts gegen Assert
1741     pTable = 0;
1742     nTableWidth = 0;
1743 }
1744 
SeekCell(short nRow,short nCol,sal_Bool bPam)1745 sal_Bool SwFltOutDoc::SeekCell(short nRow, short nCol, sal_Bool bPam)
1746 {
1747 // get structs to table cells
1748     const SwTableLines* pTableLines = &pTable->GetTabLines();
1749     SwTableLine* pTableLine = (*pTableLines)[usTableY];
1750     SwTableBoxes* pTableBoxes = &pTableLine->GetTabBoxes();
1751     SwTableBox* pTableBox = (*pTableBoxes)[usTableX];
1752 
1753     if ((sal_uInt16)nRow >= pTableLines->Count())
1754     {
1755         ASSERT((sal_uInt16)nRow >= pTableLines->Count(), "SwFltOutDoc");
1756         return sal_False;
1757     }
1758     pTableLine = (*pTableLines)[nRow];
1759     pTableBoxes = &pTableLine->GetTabBoxes();
1760     if (nCol >= pTableBoxes->Count())
1761         return sal_False;
1762     pTableBox = (*pTableBoxes)[nCol];
1763     if( !pTableBox->GetSttNd() )
1764     {
1765         ASSERT(pTableBox->GetSttNd(), "SwFltOutDoc");
1766         return sal_False;
1767     }
1768     if(bPam)
1769     {
1770         pPaM->GetPoint()->nNode = pTableBox->GetSttIdx() + 1;
1771         pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
1772 //#pragma message(__FILE__ "(?) : Sw's const problem")
1773 #if OSL_DEBUG_LEVEL > 1
1774         const SwTxtFmtColl* p = GetDoc().GetDfltTxtFmtColl();
1775         p = GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false );
1776 #endif
1777         GetDoc().SetTxtFmtColl(*pPaM,
1778             GetDoc().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ));
1779     }
1780     return sal_True;
1781 }
1782 
1783 
1784 //-----------------------------------------------------------------------------
1785 // Flys in SwFltOutBase
1786 //-----------------------------------------------------------------------------
1787 
NewFlyDefaults()1788 SfxItemSet* SwFltOutBase::NewFlyDefaults()
1789 {
1790 // Unbedingt noetige Standardwerte setzen ( falls diese Werte nicht
1791 // spaeter explizit gesetzt werden )
1792 
1793     SfxItemSet* p = new SfxItemSet( GetDoc().GetAttrPool(),
1794                                     RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1795     SwFmtFrmSize aSz( ATT_VAR_SIZE, MINFLY, MINFLY );
1796                                         // Default: Breite 100% ( = PMW:Auto )
1797     aSz.SetWidthPercent( 100 );         // Hoehe: Auto
1798     p->Put( aSz );
1799     p->Put( SwFmtHoriOrient( 0, text::HoriOrientation::NONE, text::RelOrientation::FRAME ));
1800     return p;
1801 }
1802 
BeginFly(RndStdIds eAnchor,sal_Bool bAbsolutePos,const SfxItemSet * pMoreAttrs)1803 sal_Bool SwFltOutBase::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
1804                            sal_Bool bAbsolutePos /*= sal_False*/,
1805                            const SfxItemSet*
1806 #ifdef DBG_UTIL
1807                             pMoreAttrs /*= 0*/
1808 #endif
1809                             )
1810 {
1811     ASSERT(!pMoreAttrs, "SwFltOutBase:BeginFly mit pMoreAttrs" );
1812     eFlyAnchor = eAnchor;
1813     bFlyAbsPos = bAbsolutePos;      // Bloedsinn eigentlich
1814     return sal_True;
1815 }
1816 
SetFlyAnchor(RndStdIds eAnchor)1817 /*virtual*/ void SwFltOutBase::SetFlyAnchor( RndStdIds eAnchor )
1818 {
1819     if( !IsInFly() ){
1820         ASSERT( sal_False, "SetFlyAnchor() ohne Fly" );
1821         return;
1822     }
1823     if ( eAnchor == FLY_AS_CHAR ){
1824         ASSERT( sal_False, "SetFlyAnchor( FLY_AS_CHAR ) nicht implementiert" );
1825         return;
1826     }
1827     SwFmtAnchor& rAnchor = (SwFmtAnchor&)GetFlyFrmAttr( RES_ANCHOR );
1828     rAnchor.SetType( eAnchor );
1829 }
1830 
EndFly()1831 void SwFltOutBase::EndFly()
1832 {
1833     if( bFlyAbsPos ){
1834         // hier muessen die absoluten Positionen am Fly noch in
1835         // die Writer-Koordinaten umgerechnet werden.
1836     }
1837 }
1838 
1839 //-----------------------------------------------------------------------------
1840 // Flys in SwFltDoc
1841 //-----------------------------------------------------------------------------
1842 
IsInFly()1843 /* virtual */ sal_Bool SwFltOutDoc::IsInFly()
1844 {
1845     return pFly != 0;
1846 };
1847 
MakeFly(RndStdIds eAnchor,SfxItemSet * pSet)1848 SwFrmFmt* SwFltOutDoc::MakeFly( RndStdIds eAnchor, SfxItemSet* pSet )
1849 {
1850     pFly = (SwFlyFrmFmt*)GetDoc().MakeFlySection( eAnchor, pPaM->GetPoint(),
1851                                                     pSet );
1852     return pFly;
1853 }
1854 
BeginFly(RndStdIds eAnchor,sal_Bool bAbsolutePos,const SfxItemSet * pMoreAttrs)1855 sal_Bool SwFltOutDoc::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
1856                            sal_Bool bAbsolutePos /*= sal_False*/,
1857                            const SfxItemSet* pMoreAttrs /*= 0*/ )
1858 
1859 {
1860     SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, 0 );
1861     SfxItemSet* pSet = NewFlyDefaults();
1862 
1863 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
1864 // die in Flys reinragen
1865     rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1866     rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1867 
1868 // create Fly:
1869     ASSERT(pFlySavedPos == NULL, "BeginFly in Fly");    // rekursiv geht noch nicht
1870     pFlySavedPos = new SwPosition(*pPaM->GetPoint());
1871 
1872 
1873     SwFmtAnchor aAnchor( eAnchor, 1 );
1874 
1875 // Wenn Fly-Attribute im Style waren, dann jetzt als Defaults reinsetzen
1876     if (pMoreAttrs)
1877         pSet->Put(*pMoreAttrs);
1878 
1879 //  dieses NICHT bei Seitengebundenem Fly mit Seiten-NUMMER !
1880     aAnchor.SetAnchor(pPaM->GetPoint());    // braucht erstaunlicherweise
1881                                             // den Stack nicht
1882 //  aStack.NewAttr( *pPaM->GetPoint(), SwFltAnchor( pFly ) );
1883 
1884     pSet->Put( aAnchor );
1885     SwFrmFmt* pF = MakeFly( eAnchor, pSet );
1886     delete pSet;
1887 
1888 // set pam in Fly
1889     const SwFmtCntnt& rCntnt = pF->GetCntnt();
1890     ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
1891     pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
1892     SwCntntNode *pNode = pPaM->GetCntntNode();
1893     pPaM->GetPoint()->nContent.Assign( pNode, 0 );
1894 
1895     return sal_True;
1896 }
1897 
SetFlyFrmAttr(const SfxPoolItem & rAttr)1898 /*virtual*/ void SwFltOutDoc::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1899 {
1900     if (pFly){
1901         pFly->SetFmtAttr( rAttr );
1902     }else{
1903         ASSERT(pFly, "SetFlyAttr ohne Doc-Fly");
1904         return;
1905     }
1906 }
1907 
GetFlyFrmAttr(sal_uInt16 nWhich)1908 /*virtual*/ const SfxPoolItem& SwFltOutDoc::GetFlyFrmAttr(sal_uInt16 nWhich)
1909 {
1910     if (pFly){
1911         return pFly->GetFmtAttr( nWhich );
1912     }else{
1913         ASSERT(pFly, "GetFlyAttr ohne Fly");
1914         return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1915     }
1916 }
1917 
EndFly()1918 void SwFltOutDoc::EndFly()
1919 {
1920     if( pTable ){
1921         ASSERT( sal_False, "SwFltOutDoc::EndFly() in Table" );
1922         return;
1923     }
1924                         // Alle Attribute schliessen, da sonst Attribute
1925                         // entstehen koennen, die aus Flys rausragen
1926     rStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1927     rEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
1928 
1929     *pPaM->GetPoint() = *pFlySavedPos;              // restore Cursor
1930     delete pFlySavedPos;
1931     pFlySavedPos = 0;
1932     SwFltOutBase::EndFly();
1933     pFly = 0;
1934 }
1935 
1936 //-----------------------------------------------------------------------------
1937 // Flys in SwFltFormatCollection
1938 //-----------------------------------------------------------------------------
IsInFly()1939 /*virtual*/ sal_Bool SwFltFormatCollection::IsInFly()
1940 {
1941     return bHasFly;
1942 };
1943 
SetFlyFrmAttr(const SfxPoolItem & rAttr)1944 /*virtual*/ void SwFltFormatCollection::SetFlyFrmAttr(const SfxPoolItem& rAttr)
1945 {
1946     if (!pFlyAttrs)
1947         pFlyAttrs = new SfxItemSet( GetDoc().GetAttrPool(),
1948                              RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1949     pFlyAttrs->Put( rAttr );
1950 }
1951 
GetFlyFrmAttr(sal_uInt16 nWhich)1952 /*virtual*/ const SfxPoolItem& SwFltFormatCollection::GetFlyFrmAttr(sal_uInt16 nWhich)
1953 {
1954 //  ASSERT( pFlyAttrs, "GetFlyFrmAttr ohne Coll-FlyAttrs" );
1955     if( pFlyAttrs )
1956         return pFlyAttrs->Get( nWhich, sal_False );
1957     else
1958         return GetDoc().GetAttrPool().GetDefaultItem(nWhich);
1959 }
1960 
BeginFly(RndStdIds eAnchor,sal_Bool bAbsolutePos,const SfxItemSet * pMoreAttrs)1961 sal_Bool SwFltFormatCollection::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
1962                            sal_Bool bAbsolutePos /*= sal_False*/,
1963                            const SfxItemSet* pMoreAttrs /*= 0*/ )
1964 
1965 {
1966     SwFltOutBase::BeginFly( eAnchor, bAbsolutePos, pMoreAttrs );
1967     bHasFly = sal_True;
1968     return sal_True;
1969 }
1970 
EndFly()1971 void SwFltFormatCollection::EndFly()    // Wird nie aufgerufen
1972 {
1973 }
1974 
BeginStyleFly(SwFltOutDoc * pOutDoc)1975 sal_Bool SwFltFormatCollection::BeginStyleFly( SwFltOutDoc* pOutDoc )
1976 {
1977     ASSERT( pOutDoc, "BeginStyleFly ohne pOutDoc" );
1978     ASSERT( pOutDoc && !pOutDoc->IsInFly(), "BeginStyleFly in Fly" );
1979     if( pOutDoc && !pOutDoc->IsInFly() )
1980         return pOutDoc->BeginFly( eFlyAnchor, bFlyAbsPos, pFlyAttrs );
1981     else
1982         return sal_False;
1983 }
1984 
1985 //-----------------------------------------------------------------------------
1986 // Flys in SwFltShell
1987 //-----------------------------------------------------------------------------
1988 
BeginFly(RndStdIds eAnchor,sal_Bool bAbsolutePos)1989 sal_Bool SwFltShell::BeginFly( RndStdIds eAnchor /*= FLY_AT_PARA*/,
1990                            sal_Bool bAbsolutePos /*= sal_False*/ )
1991 
1992 {
1993     if (pOut->IsInFly()){
1994         ASSERT(sal_False, "BeginFly in Fly");
1995         return sal_False;
1996     }
1997     if (pOutDoc->IsInTable()){
1998         ASSERT(sal_False, "BeginFly in Table");
1999         return sal_False;
2000     }
2001     pOut->BeginFly( eAnchor, bAbsolutePos, pColls[nAktStyle]->GetpFlyAttrs() );
2002     eSubMode = Fly;
2003     return sal_True;
2004 }
2005 
SetFlyXPos(short nXPos,sal_Int16 eHRel,sal_Int16 eHAlign)2006 void SwFltShell::SetFlyXPos( short nXPos, sal_Int16 eHRel /*= text::RelOrientation::FRAME*/,
2007                              sal_Int16 eHAlign /*= text::HoriOrientation::NONE*/ )
2008 {
2009     SetFlyFrmAttr( SwFmtHoriOrient( nXPos, eHAlign, eHRel ) );
2010 }
2011 
SetFlyYPos(short nYPos,sal_Int16 eVRel,sal_Int16 eVAlign)2012 void SwFltShell::SetFlyYPos( short nYPos, sal_Int16 eVRel /*= text::RelOrientation::FRAME*/,
2013                              sal_Int16 eVAlign /*= text::VertOrientation::NONE*/ )
2014 {
2015     SetFlyFrmAttr( SwFmtVertOrient( nYPos, eVAlign, eVRel ) );
2016 }
2017 
2018 
EndFly()2019 void SwFltShell::EndFly()
2020 {
2021     if (!pOut->IsInFly()){
2022         ASSERT(sal_False, "EndFly ohne Fly");
2023         return;
2024     }
2025     if (pOutDoc->IsInTable()){      // Table verschraenkt mit Fly macht keinen Sinn
2026         ASSERT(sal_False, "EndFly in Table ( verschraenkt )");
2027         EndTable();     // -> Table beenden
2028     }
2029     pOut->EndFly();
2030     eSubMode = None;
2031 }
2032 
2033 //-----------------------------------------------------------------------------
2034 // Fussnoten
2035 //-----------------------------------------------------------------------------
2036 
BeginFootnote()2037 void SwFltShell::BeginFootnote()
2038 {
2039     if( pOut->IsInFly() ){          // Passiert z.B. bei Fussnote in Fly
2040         ASSERT(sal_False, "Fussnote in Fly nicht erlaubt");
2041         return;
2042     }
2043     if( pOutDoc->IsInTable() ){
2044         ASSERT(sal_False, "Fussnote in Table z.Zt. nicht erlaubt");
2045         return;
2046     }
2047 
2048 // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
2049 // die in Fussnoten reinragen
2050     aStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
2051 //  aEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
2052 //  EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
2053 //  Fussnoten im PMW uebernommen werden
2054 
2055     SwFmtFtn aFtn;
2056     GetDoc().InsertPoolItem(*pPaM, aFtn, 0);
2057     ASSERT(pSavedPos == NULL, "SwFltShell");
2058     pSavedPos = new SwPosition(*pPaM->GetPoint());
2059     pPaM->Move(fnMoveBackward, fnGoCntnt);
2060     SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
2061     SwTxtAttr *const pFN = pTxt->GetTxtAttrForCharAt(
2062         pPaM->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
2063     if( !pFN ){         // Passiert z.B. bei Fussnote in Fly
2064         ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
2065         return;
2066     }
2067     const SwNodeIndex* pStartIndex = ((SwTxtFtn*)pFN)->GetStartNode();
2068     ASSERT(pStartIndex, "Probleme beim Anlegen des Fussnoten-Textes");
2069     pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2070     pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2071     eSubMode = Footnote;
2072 }
2073 
EndFootnote()2074 void SwFltShell::EndFootnote()
2075 {
2076     if(!pSavedPos)
2077         return;
2078                         // Alle Attribute schliessen, da sonst Attribute
2079                         // entstehen koennen, die aus Fussnoten rausragen
2080     aStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
2081 //  aEndStack.SetAttr( *pPaM->GetPoint(), 0, sal_False );
2082 //  EndStack erstmal nicht zwangs-Schliessen, damit Bookmarks ueber
2083 //  Fussnoten im PMW uebernommen werden
2084 
2085     *pPaM->GetPoint() = *pSavedPos;             // restore Cursor
2086     delete pSavedPos;
2087     pSavedPos = 0;
2088 }
2089 
BeginHeader(SwPageDesc *)2090 void SwFltShell::BeginHeader(SwPageDesc* /*pPD*/)
2091 {
2092     SwFrmFmt* pFmt = &pCurrentPageDesc->GetMaster(
2093      ); //(bUseLeft) ?  &pCurrentPageDesc->GetLeft() :
2094     SwFrmFmt* pHdFtFmt;
2095     pFmt->SetFmtAttr(SwFmtHeader(sal_True));
2096     pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt();
2097     const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
2098     if (!pStartIndex)
2099         return;
2100     ASSERT(pSavedPos == NULL, "SwFltShell");
2101     pSavedPos = new SwPosition(*pPaM->GetPoint());
2102     pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2103     pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2104     eSubMode = Header;
2105 }
2106 
BeginFooter(SwPageDesc *)2107 void SwFltShell::BeginFooter(SwPageDesc* /*pPD*/)
2108 {
2109     SwFrmFmt* pFmt =  &pCurrentPageDesc->GetMaster(
2110      ); //(bUseLeft) ?  &pCurrentPageDesc->GetLeft() :
2111     SwFrmFmt* pHdFtFmt;
2112     pFmt->SetFmtAttr(SwFmtFooter(sal_True));
2113     pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt();
2114     const SwNodeIndex* pStartIndex = pHdFtFmt->GetCntnt().GetCntntIdx();
2115     if (!pStartIndex)
2116         return;
2117     ASSERT(pSavedPos == NULL, "SwFltShell");
2118     pSavedPos = new SwPosition(*pPaM->GetPoint());
2119     pPaM->GetPoint()->nNode = pStartIndex->GetIndex() + 1;
2120     pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(), 0);
2121     eSubMode = Footer;
2122 }
2123 
EndHeaderFooter()2124 void SwFltShell::EndHeaderFooter()
2125 {
2126     *pPaM->GetPoint() = *pSavedPos;             // restore Cursor
2127     delete pSavedPos;
2128     pSavedPos = 0;
2129 }
2130 
MakePageDesc(SwPageDesc * pFirstPageDesc)2131 SwPageDesc* SwFltShell::MakePageDesc(SwPageDesc* pFirstPageDesc)
2132 {
2133     if(bStdPD)                      // keine Neuen PageDescs
2134         return pCurrentPageDesc;
2135 
2136     sal_Bool bFollow = (pFirstPageDesc != 0);
2137     SwPageDesc* pNewPD;
2138     sal_uInt16 nPos;
2139     if (bFollow && pFirstPageDesc->GetFollow() != pFirstPageDesc)
2140         return pFirstPageDesc;      // Fehler: hat schon Follow
2141 // Erkennung doppelter Namen fehlt noch (Wahrscheinlichkeit
2142 // fuer dopp. Namen ist gering)
2143 
2144     nPos = GetDoc().MakePageDesc( ViewShell::GetShellRes()->GetPageDescName(
2145                                 GetDoc().GetPageDescCnt(), sal_False, bFollow ),
2146                                 pFirstPageDesc, sal_False );
2147 
2148     pNewPD =  &((SwPageDesc&)const_cast<const SwDoc &>(GetDoc()).
2149                 GetPageDesc(nPos));
2150     if (bFollow)
2151     {               // Dieser ist der folgende von pPageDesc
2152         pFirstPageDesc->SetFollow(pNewPD);
2153         pNewPD->SetFollow(pNewPD);
2154     }
2155     else
2156     {
2157         GetDoc().InsertPoolItem( *pPaM, SwFmtPageDesc( pNewPD ), 0 );
2158     }
2159     pNewPD->WriteUseOn( // alle Seiten
2160      (UseOnPage)(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE));
2161     return pNewPD;
2162 }
2163 
2164 ///////////////////////////////////////////////// SwFltFormatCollection
SwFltFormatCollection(SwDoc & _rDoc,RES_POOL_COLLFMT_TYPE nType)2165 SwFltFormatCollection::SwFltFormatCollection(
2166     SwDoc& _rDoc, RES_POOL_COLLFMT_TYPE nType ) :
2167     SwFltOutBase(_rDoc),
2168     pColl(_rDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(nType), false )),
2169     pFlyAttrs( 0 ),
2170     bHasFly( sal_False )
2171 {
2172     Reset();            // Default-Attrs loeschen und Auto-Flag
2173 }
2174 
SwFltFormatCollection(SwDoc & _rDoc,const String & rName)2175 SwFltFormatCollection::SwFltFormatCollection(
2176     SwDoc& _rDoc, const String& rName ) :
2177     SwFltOutBase(_rDoc),
2178     pFlyAttrs( 0 ),
2179     bHasFly( sal_False )
2180 {
2181     pColl = _rDoc.MakeTxtFmtColl(rName, (SwTxtFmtColl*)_rDoc.GetDfltTxtFmtColl());
2182     Reset();            // Default-Attrs loeschen und Auto-Flag
2183 }
2184 
NextStyle(sal_uInt16 nWhich,sal_uInt16 nNext)2185 void SwFltShell::NextStyle(sal_uInt16 nWhich, sal_uInt16 nNext)
2186 {
2187         ASSERT(pColls[nWhich], "Next style for noexistent style" );
2188         ASSERT(pColls[nNext], "Next style to noexistent style" );
2189         if( pColls[nWhich] && pColls[nNext] )
2190             pColls[nWhich]->GetColl()->SetNextTxtFmtColl(
2191                  *pColls[nNext]->GetColl() );
2192 }
2193 
2194 // UpdatePageDescs muss am Ende des Einlesevorganges aufgerufen werden, damit
2195 // der Writer den Inhalt der Pagedescs wirklich akzeptiert
UpdatePageDescs(SwDoc & rDoc,sal_uInt16 nInPageDescOffset)2196 void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset)
2197 {
2198     // Pagedescriptoren am Dokument updaten (nur so werden auch die
2199     // linken Seiten usw. eingestellt).
2200 
2201     // PageDesc "Standard"
2202     rDoc.ChgPageDesc(0, const_cast<const SwDoc &>(rDoc).GetPageDesc(0));
2203 
2204     // PageDescs "Konvert..."
2205     for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i)
2206         rDoc.ChgPageDesc(i, const_cast<const SwDoc &>(rDoc).GetPageDesc(i));
2207 }
2208 
2209 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
2210