LCOV - code coverage report
Current view: top level - sw/source/filter/basflt - fltshell.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 241 414 58.2 %
Date: 2014-11-03 Functions: 34 49 69.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <ctype.h>
      21             : #include <hintids.hxx>
      22             : #include <hints.hxx>
      23             : #include <vcl/graphicfilter.hxx>
      24             : 
      25             : #include <vcl/graph.hxx>
      26             : #include <svl/urihelper.hxx>
      27             : #include <editeng/boxitem.hxx>
      28             : #include <editeng/wghtitem.hxx>
      29             : #include <editeng/cmapitem.hxx>
      30             : #include <editeng/contouritem.hxx>
      31             : #include <editeng/postitem.hxx>
      32             : #include <editeng/crossedoutitem.hxx>
      33             : #include <svl/stritem.hxx>
      34             : #include <unotools/charclass.hxx>
      35             : #include <txtftn.hxx>
      36             : #include <fmtpdsc.hxx>
      37             : #include <fmtftn.hxx>
      38             : #include <fmtanchr.hxx>
      39             : #include <fmtrfmrk.hxx>
      40             : #include <fmtclds.hxx>
      41             : #include <fmtfld.hxx>
      42             : #include <fmtfsize.hxx>
      43             : #include <fmthdft.hxx>
      44             : #include <fmtcntnt.hxx>
      45             : #include <redline.hxx>
      46             : #include <pam.hxx>
      47             : #include <doc.hxx>
      48             : #include <IDocumentFieldsAccess.hxx>
      49             : #include <IDocumentRedlineAccess.hxx>
      50             : #include <IDocumentStylePoolAccess.hxx>
      51             : #include <IDocumentState.hxx>
      52             : #include <IDocumentLayoutAccess.hxx>
      53             : #include <ndtxt.hxx>
      54             : #include <frmatr.hxx>
      55             : #include <fldbas.hxx>
      56             : #include <charatr.hxx>
      57             : #include <swtable.hxx>
      58             : #include <tox.hxx>
      59             : #include <expfld.hxx>
      60             : #include <section.hxx>
      61             : #include <tblsel.hxx>
      62             : #include <pagedesc.hxx>
      63             : #include <docsh.hxx>
      64             : #include <fltshell.hxx>
      65             : #include <viewsh.hxx>
      66             : #include <shellres.hxx>
      67             : 
      68             : using namespace com::sun::star;
      69             : 
      70       53484 : static SwCntntNode* GetCntntNode(SwDoc* pDoc, SwNodeIndex& rIdx, bool bNext)
      71             : {
      72       53484 :     SwCntntNode * pCNd = rIdx.GetNode().GetCntntNode();
      73       53678 :     if(!pCNd && 0 == (pCNd = bNext ? pDoc->GetNodes().GoNext(&rIdx)
      74         194 :                                      : pDoc->GetNodes().GoPrevious(&rIdx)))
      75             :     {
      76           0 :         pCNd = bNext ? pDoc->GetNodes().GoPrevious(&rIdx)
      77           0 :                      : pDoc->GetNodes().GoNext(&rIdx);
      78             :         OSL_ENSURE(pCNd, "no ContentNode found");
      79             :     }
      80       53484 :     return pCNd;
      81             : }
      82             : 
      83             : // Stack entry for all text attributes
      84       51084 : SwFltStackEntry::SwFltStackEntry(const SwPosition& rStartPos, SfxPoolItem* pHt)
      85             :     : m_aMkPos(rStartPos)
      86             :     , m_aPtPos(rStartPos)
      87             :     , mnStartCP(-1)
      88             :     , mnEndCP(-1)
      89       51084 :     , bIsParaEnd(false)
      90             : {
      91       51084 :     pAttr = pHt;            // store a copy of the attribute
      92       51084 :     bOld    = false;    // used for marking Attributes *before* skipping field results
      93       51084 :     bOpen = true;       // lock the attribute --> may first
      94       51084 :     bConsumedByField = false;
      95       51084 : }
      96             : 
      97      102168 : SwFltStackEntry::~SwFltStackEntry()
      98             : {
      99             :     // Although attribute got passed as pointer, it gets deleted here
     100       51084 :     delete pAttr;
     101       51084 : }
     102             : 
     103       52192 : void SwFltStackEntry::SetEndPos(const SwPosition& rEndPos)
     104             : {
     105             :     // Release attribute and keep track of end
     106             :     // Everything with sal_uInt16s, lest the inserting of new text at
     107             :     // the cursor position moves the attribute's range
     108             :     // That's not the desired behavior!
     109       52192 :     bOpen = false;                  // release and remember END
     110       52192 :     m_aPtPos.SetPos(rEndPos);
     111       52192 : }
     112             : 
     113       48574 : bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck,
     114             :     const SwFltPosition &rMkPos, const SwFltPosition &rPtPos, bool bIsParaEnd,
     115             :     sal_uInt16 nWhich)
     116             : {
     117             :     // does this range actually contain something?
     118             :     // empty range is allowed if at start of empty paragraph
     119             :     // fields are special: never have range, so leave them
     120             : 
     121             :     // The only position of 0x0D will not be able to make region in the old logic
     122             :     // because it is beyond the length of para...need special consideration here.
     123             :     SwCntntNode *const pCntntNode(
     124       48574 :         SwNodeIndex(rMkPos.m_nNode, +1).GetNode().GetCntntNode());
     125      108822 :     if (rMkPos == rPtPos &&
     126       21304 :         ((0 != rPtPos.m_nCntnt) || (pCntntNode && (0 != pCntntNode->Len())))
     127        7078 :         && ( RES_TXTATR_FIELD != nWhich
     128        7078 :              && RES_TXTATR_ANNOTATION != nWhich
     129        7078 :              && RES_TXTATR_INPUTFIELD != nWhich )
     130       55652 :         && !(bIsParaEnd && pCntntNode && pCntntNode->IsTxtNode() && 0 != pCntntNode->Len() ))
     131             :     {
     132        6792 :         return false;
     133             :     }
     134             :     // The content indices always apply to the node!
     135       41782 :     rRegion.GetPoint()->nNode = rMkPos.m_nNode.GetIndex() + 1;
     136       41782 :     SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, true);
     137       41782 :     rRegion.GetPoint()->nContent.Assign(pCNd, rMkPos.m_nCntnt);
     138       41782 :     rRegion.SetMark();
     139       41782 :     if (rMkPos.m_nNode != rPtPos.m_nNode)
     140             :     {
     141       11486 :         rRegion.GetPoint()->nNode = rPtPos.m_nNode.GetIndex() + 1;
     142       11486 :         pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, false);
     143             :     }
     144       41782 :     rRegion.GetPoint()->nContent.Assign(pCNd, rPtPos.m_nCntnt);
     145             :     OSL_ENSURE( CheckNodesRange( rRegion.Start()->nNode,
     146             :                              rRegion.End()->nNode, true ),
     147             :              "atttribute or similar crosses section-boundaries" );
     148       41782 :     if( bCheck )
     149          32 :         return CheckNodesRange( rRegion.Start()->nNode,
     150          64 :                                 rRegion.End()->nNode, true );
     151             :     else
     152       41750 :         return true;
     153             : }
     154             : 
     155       48558 : bool SwFltStackEntry::MakeRegion(SwDoc* pDoc, SwPaM& rRegion, bool bCheck) const
     156             : {
     157             :     return MakeRegion(pDoc, rRegion, bCheck, m_aMkPos, m_aPtPos, bIsParaEnd,
     158       48558 :         pAttr->Which());
     159             : }
     160             : 
     161        1744 : SwFltControlStack::SwFltControlStack(SwDoc* pDo, sal_uLong nFieldFl)
     162        1744 :     : nFieldFlags(nFieldFl),bHasSdOD(true), bSdODChecked(false), pDoc(pDo), bIsEndStack(false)
     163             : {
     164        1744 : }
     165             : 
     166        1744 : SwFltControlStack::~SwFltControlStack()
     167             : {
     168             :     OSL_ENSURE(maEntries.empty(), "There are still Attributes on the stack");
     169        1744 : }
     170             : 
     171             : // MoveAttrs() is meant to address the following problem:
     172             : // When a field like "set variable" is set through the stack, the text
     173             : // is shifted by one \xff character, which makes all subsequent
     174             : // attribute positions invalid.
     175             : // After setting the attribute in the doc, MoveAttrs() needs to be
     176             : // called in order to push all attribute positions to the right in the
     177             : // same paragraph further out by one character.
     178           0 : void SwFltControlStack::MoveAttrs( const SwPosition& rPos )
     179             : {
     180           0 :     size_t nCnt = maEntries.size();
     181           0 :     sal_uLong nPosNd = rPos.nNode.GetIndex();
     182           0 :     sal_uInt16 nPosCt = rPos.nContent.GetIndex() - 1;
     183             : 
     184           0 :     for (size_t i=0; i < nCnt; ++i)
     185             :     {
     186           0 :         SwFltStackEntry& rEntry = maEntries[i];
     187           0 :         if (
     188           0 :             (rEntry.m_aMkPos.m_nNode.GetIndex()+1 == nPosNd) &&
     189           0 :             (rEntry.m_aMkPos.m_nCntnt >= nPosCt)
     190             :            )
     191             :         {
     192           0 :             rEntry.m_aMkPos.m_nCntnt++;
     193             :             OSL_ENSURE( rEntry.m_aMkPos.m_nCntnt
     194             :                 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
     195             :                     "Attribute ends after end of line" );
     196             :         }
     197           0 :         if (
     198           0 :             (rEntry.m_aPtPos.m_nNode.GetIndex()+1 == nPosNd) &&
     199           0 :             (rEntry.m_aPtPos.m_nCntnt >= nPosCt)
     200             :            )
     201             :         {
     202           0 :             rEntry.m_aPtPos.m_nCntnt++;
     203             :             OSL_ENSURE( rEntry.m_aPtPos.m_nCntnt
     204             :                 <= pDoc->GetNodes()[nPosNd]->GetCntntNode()->Len(),
     205             :                     "Attribute ends after end of line" );
     206             :         }
     207             :     }
     208           0 : }
     209             : 
     210          68 : void SwFltControlStack::MarkAllAttrsOld()
     211             : {
     212          68 :     size_t nCnt = maEntries.size();
     213         790 :     for (sal_uInt16 i=0; i < nCnt; ++i)
     214         722 :         maEntries[i].bOld = true;
     215          68 : }
     216             : 
     217             : namespace
     218             : {
     219       52614 :     bool couldExtendEntry(const SwFltStackEntry *pExtendCandidate,
     220             :         const SfxPoolItem& rAttr)
     221             :     {
     222        5824 :         return (pExtendCandidate &&
     223       11648 :                 !pExtendCandidate->bConsumedByField &&
     224             :                 //potentially more, but lets keep it simple
     225       67368 :                 (isPARATR_LIST(rAttr.Which()) || (isCHRATR(rAttr.Which()) && rAttr.Which() != RES_CHRATR_FONT && rAttr.Which() != RES_CHRATR_FONTSIZE)) &&
     226       55720 :                 *(pExtendCandidate->pAttr) == rAttr);
     227             :     }
     228             : }
     229             : 
     230       52614 : void SwFltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem& rAttr)
     231             : {
     232       52614 :     sal_uInt16 nWhich = rAttr.Which();
     233             :     // Set end position of potentially equal attributes on stack, so
     234             :     // as to avoid having them accumulate
     235       52614 :     SwFltStackEntry *pExtendCandidate = SetAttr(rPos, nWhich);
     236       52614 :     if (couldExtendEntry(pExtendCandidate, rAttr))
     237             :     {
     238             :         //Here we optimize by seeing if there is an attribute uncommited
     239             :         //to the document which
     240             : 
     241             :         //a) has the same value as this attribute
     242             :         //b) is already open, or ends at the same place as where we're starting
     243             :         //from. If so we merge it with this one and elide adding another
     244             :         //to the stack
     245        1540 :         pExtendCandidate->SetEndPos(rPos);
     246        1540 :         pExtendCandidate->bOpen=true;
     247             :     }
     248             :     else
     249             :     {
     250       51074 :         SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone() );
     251       51074 :         pTmp->SetStartCP(GetCurrAttrCP());
     252       51074 :         maEntries.push_back(pTmp);
     253             :     }
     254       52614 : }
     255             : 
     256        2522 : void SwFltControlStack::DeleteAndDestroy(Entries::size_type nCnt)
     257             : {
     258             :     OSL_ENSURE(nCnt < maEntries.size(), "Out of range!");
     259        2522 :     if (nCnt < maEntries.size())
     260             :     {
     261        2522 :         myEIter aElement = maEntries.begin() + nCnt;
     262        2522 :         maEntries.erase(aElement);
     263             :     }
     264             :     //Clear the para end position recorded in reader intermittently for the least impact on loading performance
     265             :     //Because the attributes handled based on the unit of para
     266        2522 :     if ( empty() )
     267             :     {
     268         402 :         ClearParaEndPosition();
     269         402 :         bHasSdOD = true;
     270         402 :         bSdODChecked = false;
     271             :     }
     272        2522 : }
     273             : 
     274             : // SwFltControlStack::StealAttr() removes attributes of the given type
     275             : // from the stack. Allowed as nAttrId: 0 meaning any, or a specific
     276             : // type.  This makes them disappear from the doc structure. Only
     277             : // attributes from the same paragraph as rPos are removed. Used for
     278             : // graphic apos -> images.
     279           0 : void SwFltControlStack::StealAttr(const SwNodeIndex& rNode, sal_uInt16 nAttrId)
     280             : {
     281           0 :     size_t nCnt = maEntries.size();
     282             : 
     283           0 :     while (nCnt)
     284             :     {
     285           0 :         nCnt --;
     286           0 :         SwFltStackEntry& rEntry = maEntries[nCnt];
     287           0 :         if (rEntry.m_aPtPos.m_nNode.GetIndex()+1 == rNode.GetIndex() &&
     288           0 :             (!nAttrId || nAttrId == rEntry.pAttr->Which()))
     289             :         {
     290           0 :             DeleteAndDestroy(nCnt);     // loesche aus dem Stack
     291             :         }
     292             :     }
     293           0 : }
     294             : 
     295             : // SwFltControlStack::KillUnlockedAttr() removes all attributes from
     296             : // the stack, which are assigned to an rPos. This makes them disappear
     297             : // from the doc structure. Used in WW import for ignoring attributes
     298             : // assigned to the 0x0c section break symbol.
     299         192 : void SwFltControlStack::KillUnlockedAttrs(const SwPosition& rPos)
     300             : {
     301         192 :     SwFltPosition aFltPos(rPos);
     302             : 
     303         192 :     size_t nCnt = maEntries.size();
     304        2064 :     while( nCnt )
     305             :     {
     306        1680 :         nCnt --;
     307        1680 :         SwFltStackEntry& rEntry = maEntries[nCnt];
     308        3360 :         if(    !rEntry.bOld
     309         958 :             && !rEntry.bOpen
     310         598 :             && (rEntry.m_aMkPos == aFltPos)
     311        2164 :             && (rEntry.m_aPtPos == aFltPos))
     312             :         {
     313         484 :             DeleteAndDestroy( nCnt ); // remove from stack
     314             :         }
     315         192 :     }
     316         192 : }
     317             : 
     318             : // Unlock all locked attributes and move to the end, all others will
     319             : // be applied to the document and removed from the stack.
     320             : // Returns if there were any selected attributes on the stack
     321      104102 : SwFltStackEntry* SwFltControlStack::SetAttr(const SwPosition& rPos,
     322             :     sal_uInt16 nAttrId, bool bTstEnde, long nHand,
     323             :     bool consumedByField)
     324             : {
     325      104102 :     SwFltStackEntry *pRet = NULL;
     326             : 
     327      104102 :     SwFltPosition aFltPos(rPos);
     328             : 
     329             :     OSL_ENSURE(!nAttrId ||
     330             :         (POOLATTR_BEGIN <= nAttrId && POOLATTR_END > nAttrId) ||
     331             :         (RES_FLTRATTR_BEGIN <= nAttrId && RES_FLTRATTR_END > nAttrId),
     332             :         "Wrong id for attribute");
     333             : 
     334      104102 :     myEIter aI = maEntries.begin();
     335     3092860 :     while (aI != maEntries.end())
     336             :     {
     337     2884656 :         bool bLastEntry = aI == maEntries.end() - 1;
     338             : 
     339     2884656 :         SwFltStackEntry& rEntry = *aI;
     340     2884656 :         if (rEntry.bOpen)
     341             :         {
     342             :             // set end of attribute
     343      450368 :             bool bF = false;
     344      450368 :             if (!nAttrId )
     345             :             {
     346          46 :                 bF = true;
     347             :             }
     348      450322 :             else if (nAttrId == rEntry.pAttr->Which())
     349             :             {
     350       50600 :                 if( nAttrId != RES_FLTR_BOOKMARK )
     351             :                 {
     352             :                     // query handle
     353       50548 :                     bF = true;
     354             :                 }
     355          52 :                 else if (nHand == ((SwFltBookmark*)(rEntry.pAttr))->GetHandle())
     356             :                 {
     357          48 :                     bF = true;
     358             :                 }
     359             :             }
     360      450368 :             if (bF)
     361             :             {
     362       50642 :                 rEntry.bConsumedByField = consumedByField;
     363       50642 :                 rEntry.SetEndPos(rPos);
     364       50642 :                 rEntry.SetEndCP(GetCurrAttrCP());
     365       50642 :                 if (bLastEntry && nAttrId == rEntry.pAttr->Which())
     366             :                 {
     367             :                     //potential candidate for merging with an identical
     368             :                     //property beginning at rPos
     369       14280 :                     pRet = &rEntry;
     370             :                 }
     371             :             }
     372      450368 :             ++aI;
     373      450368 :             continue;
     374             :         }
     375             : 
     376             :         // if the end position is equal to the cursor position, then
     377             :         // refrain from applying it; there needs to be following text,
     378             :         // except at the very end. (attribute expansion !!)
     379             :         // Never apply end stack except at document ending
     380     2434288 :         if (bTstEnde)
     381             :         {
     382     2430834 :             if (bIsEndStack)
     383             :             {
     384         166 :                 ++aI;
     385         166 :                 continue;
     386             :             }
     387             : 
     388             :             //defer inserting this attribute into the document until
     389             :             //we advance to the next node, or finish processing the document
     390     2430668 :             if (rEntry.m_aPtPos.m_nNode.GetIndex() == aFltPos.m_nNode.GetIndex())
     391             :             {
     392     2391090 :                 if (bLastEntry && nAttrId == rEntry.pAttr->Which() &&
     393        5520 :                     rEntry.m_aPtPos.m_nCntnt == aFltPos.m_nCntnt)
     394             :                 {
     395             :                     //potential candidate for merging with an identical
     396             :                     //property beginning at rPos
     397        5470 :                     pRet = &rEntry;
     398             :                 }
     399             : 
     400     2385570 :                 ++aI;
     401     2385570 :                 continue;
     402             :             }
     403             :         }
     404       48552 :         SetAttrInDoc(rPos, rEntry);
     405       48552 :         aI = maEntries.erase(aI);
     406             :     }
     407             : 
     408      104102 :     return pRet;
     409             : }
     410             : 
     411         216 : static void MakePoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
     412             :     SwPaM& rRegion)
     413             : {
     414             :     // the anchor is the Pam's Point. It's modified when inserting
     415             :     // text, etc.; therefore it is kept on the stack. Only the
     416             :     // attribute's format needs to be set.
     417         216 :     rRegion.DeleteMark();
     418         216 :     rRegion.GetPoint()->nNode = rEntry.m_aMkPos.m_nNode.GetIndex() + 1;
     419         216 :     SwCntntNode* pCNd = GetCntntNode(pDoc, rRegion.GetPoint()->nNode, true);
     420         216 :     rRegion.GetPoint()->nContent.Assign(pCNd, rEntry.m_aMkPos.m_nCntnt);
     421         216 : }
     422             : 
     423             : // MakeBookRegionOrPoint() behaves like MakeRegionOrPoint, except that
     424             : // it adheres to certain restrictions on bookmarks in tables (cannot
     425             : // span more than one cell)
     426          44 : static void MakeBookRegionOrPoint(const SwFltStackEntry& rEntry, SwDoc* pDoc,
     427             :                     SwPaM& rRegion, bool bCheck )
     428             : {
     429          44 :     if (rEntry.MakeRegion(pDoc, rRegion, bCheck )){
     430             :         // sal_Bool b1 = rNds[rRegion.GetPoint()->nNode]->FindTableNode() != 0;
     431          44 :         if (rRegion.GetPoint()->nNode.GetNode().FindTableBoxStartNode()
     432          22 :               != rRegion.GetMark()->nNode.GetNode().FindTableBoxStartNode())
     433             :         {
     434           0 :             rRegion.Exchange();         // invalid range
     435           0 :             rRegion.DeleteMark();       // -> both to mark
     436             :         }
     437             :     }else{
     438          22 :         MakePoint(rEntry, pDoc, rRegion);
     439             :     }
     440          44 : }
     441             : 
     442             : // IterateNumrulePiece() looks for the first range valid for Numrules
     443             : // between rTmpStart and rEnd.
     444             : 
     445             : // rNds denotes the doc nodes
     446             : // rEnd denotes the range end,
     447             : // rTmpStart is an in/out parameter: in: start of range to be searched,
     448             : //                                   out: start of valid range
     449             : // rTmpEnd is an out parameter
     450             : // Returns true for valid range
     451           0 : static bool IterateNumrulePiece( const SwNodeIndex& rEnd,
     452             :                                 SwNodeIndex& rTmpStart, SwNodeIndex& rTmpEnd )
     453             : {
     454           0 :     while( ( rTmpStart <= rEnd )
     455           0 :            && !( rTmpStart.GetNode().IsTxtNode() ) )    // look for valid start
     456           0 :         ++rTmpStart;
     457             : 
     458           0 :     rTmpEnd = rTmpStart;
     459           0 :     while( ( rTmpEnd <= rEnd )
     460           0 :            && ( rTmpEnd.GetNode().IsTxtNode() ) )       // look for valid end + 1
     461           0 :         ++rTmpEnd;
     462             : 
     463           0 :     rTmpEnd--;                                      // valid end
     464             : 
     465           0 :     return rTmpStart <= rTmpEnd;                    // valid ?
     466             : }
     467             : 
     468             : //***This function will check whether there is existing individual attribute position for 0x0D***/
     469             : //The check will happen only once for a paragraph during loading
     470         312 : bool SwFltControlStack::HasSdOD()
     471             : {
     472         312 :     bool bRet = false;
     473             : 
     474        2432 :     for (Entries::iterator it = maEntries.begin(); it != maEntries.end(); ++it)
     475             :     {
     476        2162 :         SwFltStackEntry& rEntry = *it;
     477        2162 :         if ( rEntry.mnStartCP == rEntry.mnEndCP )
     478             :         {
     479         412 :             if ( CheckSdOD(rEntry.mnStartCP,rEntry.mnEndCP) )
     480             :             {
     481          42 :                 bRet = true;
     482          42 :                 break;
     483             :             }
     484             :         }
     485             :     }
     486             : 
     487         312 :     return bRet;
     488             : }
     489             : 
     490       45390 : void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
     491             :     SwFltStackEntry& rEntry)
     492             : {
     493       45390 :     SwPaM aRegion( rTmpPos );
     494             : 
     495       45390 :     switch(rEntry.pAttr->Which())
     496             :     {
     497             :     case RES_FLTR_ANCHOR:
     498             :         {
     499         194 :             SwFrmFmt* pFmt = ((SwFltAnchor*)rEntry.pAttr)->GetFrmFmt();
     500         194 :             if (pFmt != NULL)
     501             :             {
     502         194 :                 MakePoint(rEntry, pDoc, aRegion);
     503         194 :                 SwFmtAnchor aAnchor(pFmt->GetAnchor());
     504         194 :                 aAnchor.SetAnchor(aRegion.GetPoint());
     505         194 :                 pFmt->SetFmtAttr(aAnchor);
     506             :                 // So the frames will be created when inserting into
     507             :                 // existing doc (after setting the anchor!):
     508         388 :                 if(pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()
     509         194 :                    && (FLY_AT_PARA == pFmt->GetAnchor().GetAnchorId()))
     510             :                 {
     511           0 :                     pFmt->MakeFrms();
     512         194 :                 }
     513             :             }
     514             :         }
     515         194 :         break;
     516             : 
     517             :     case RES_TXTATR_FIELD:
     518             :     case RES_TXTATR_ANNOTATION:
     519             :     case RES_TXTATR_INPUTFIELD:
     520           0 :         break;
     521             : 
     522             :     case RES_TXTATR_TOXMARK:
     523           0 :         break;
     524             : 
     525             :     case RES_FLTR_NUMRULE:          // insert Numrule
     526             :         {
     527           0 :             const OUString& rNumNm = ((SfxStringItem*)rEntry.pAttr)->GetValue();
     528           0 :             SwNumRule* pNumRule = pDoc->FindNumRulePtr( rNumNm );
     529           0 :             if( pNumRule )
     530             :             {
     531           0 :                 if( rEntry.MakeRegion(pDoc, aRegion, true))
     532             :                 {
     533           0 :                     SwNodeIndex aTmpStart( aRegion.Start()->nNode );
     534           0 :                     SwNodeIndex aTmpEnd( aTmpStart );
     535           0 :                     SwNodeIndex& rRegEndNd = aRegion.End()->nNode;
     536           0 :                     while( IterateNumrulePiece( rRegEndNd,
     537             :                                                 aTmpStart, aTmpEnd ) )
     538             :                     {
     539           0 :                         SwPaM aTmpPam( aTmpStart, aTmpEnd );
     540             :                         // no start of a new list
     541           0 :                         pDoc->SetNumRule( aTmpPam, *pNumRule, false );
     542             : 
     543           0 :                         aTmpStart = aTmpEnd;    // here starts the next range
     544           0 :                         ++aTmpStart;
     545           0 :                     }
     546             :                 }
     547             :                 else
     548           0 :                     pDoc->DelNumRule( rNumNm );
     549             :             }
     550             :         }
     551           0 :         break;
     552             : 
     553             :     case RES_FLTR_BOOKMARK:
     554             :         {
     555          48 :             SwFltBookmark* pB = (SwFltBookmark*)rEntry.pAttr;
     556          48 :             const OUString& rName = ((SwFltBookmark*)rEntry.pAttr)->GetName();
     557             : 
     558          48 :             if (IsFlagSet(BOOK_TO_VAR_REF))
     559             :             {
     560           0 :                 SwFieldType* pFT = pDoc->getIDocumentFieldsAccess().GetFldType(RES_SETEXPFLD, rName, false);
     561           0 :                 if (!pFT)
     562             :                 {
     563           0 :                     SwSetExpFieldType aS(pDoc, rName, nsSwGetSetExpType::GSE_STRING);
     564           0 :                     pFT = pDoc->getIDocumentFieldsAccess().InsertFldType(aS);
     565             :                 }
     566           0 :                 SwSetExpField aFld((SwSetExpFieldType*)pFT, pB->GetValSys());
     567           0 :                 aFld.SetSubType( nsSwExtendedSubType::SUB_INVISIBLE );
     568           0 :                 MakePoint(rEntry, pDoc, aRegion);
     569           0 :                 pDoc->getIDocumentContentOperations().InsertPoolItem(aRegion, SwFmtFld(aFld), 0);
     570           0 :                 MoveAttrs( *(aRegion.GetPoint()) );
     571             :             }
     572          96 :             if ( ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) &&
     573          48 :                  !rEntry.bConsumedByField )
     574             :             {
     575          44 :                 MakeBookRegionOrPoint(rEntry, pDoc, aRegion, true);
     576             :                 // #i120879# - create a cross reference heading bookmark if appropriate.
     577             :                 const IDocumentMarkAccess::MarkType eBookmarkType =
     578          44 :                     ( pB->IsTOCBookmark() &&
     579           0 :                       IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aRegion ) )
     580             :                     ? IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK
     581          44 :                     : IDocumentMarkAccess::BOOKMARK;
     582          44 :                 pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, eBookmarkType );
     583             :             }
     584             :         }
     585          48 :         break;
     586             :     case RES_FLTR_TOX:
     587             :         {
     588           0 :             MakePoint(rEntry, pDoc, aRegion);
     589             : 
     590           0 :             SwPosition* pPoint = aRegion.GetPoint();
     591             : 
     592           0 :             SwFltTOX* pTOXAttr = (SwFltTOX*)rEntry.pAttr;
     593             : 
     594             :             // test if on this node there had been a pagebreak BEFORE the
     595             :             //     tox attribute was put on the stack
     596           0 :             SfxItemSet aBkSet( pDoc->GetAttrPool(), RES_PAGEDESC, RES_BREAK );
     597           0 :             SwCntntNode* pNd = 0;
     598           0 :             if( !pTOXAttr->HadBreakItem() || !pTOXAttr->HadPageDescItem() )
     599             :             {
     600           0 :                 pNd = pPoint->nNode.GetNode().GetCntntNode();
     601           0 :                 if( pNd )
     602             :                 {
     603           0 :                     const SfxItemSet* pSet = pNd->GetpSwAttrSet();
     604             :                     const SfxPoolItem* pItem;
     605           0 :                     if( pSet )
     606             :                     {
     607           0 :                         if(    !pTOXAttr->HadBreakItem()
     608           0 :                             && SfxItemState::SET == pSet->GetItemState( RES_BREAK, false, &pItem ) )
     609             :                         {
     610           0 :                             aBkSet.Put( *pItem );
     611           0 :                             pNd->ResetAttr( RES_BREAK );
     612             :                         }
     613           0 :                         if(    !pTOXAttr->HadPageDescItem()
     614           0 :                             && SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem ) )
     615             :                         {
     616           0 :                             aBkSet.Put( *pItem );
     617           0 :                             pNd->ResetAttr( RES_PAGEDESC );
     618             :                         }
     619             :                     }
     620             :                 }
     621             :             }
     622             : 
     623           0 :             delete pTOXAttr->GetBase();
     624             : 
     625             :             // set (aboved saved and removed) the break item at the node following the TOX
     626           0 :             if( aBkSet.Count() )
     627           0 :                 pNd->SetAttr( aBkSet );
     628             :         }
     629           0 :         break;
     630             :     case RES_FLTR_REDLINE:
     631             :         {
     632           0 :             if (rEntry.MakeRegion(pDoc, aRegion, true))
     633             :             {
     634           0 :               pDoc->getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)(   nsRedlineMode_t::REDLINE_ON
     635             :                                               | nsRedlineMode_t::REDLINE_SHOW_INSERT
     636           0 :                                               | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
     637           0 :                 SwFltRedline& rFltRedline = *((SwFltRedline*)rEntry.pAttr);
     638             : 
     639           0 :                 if( USHRT_MAX != rFltRedline.nAutorNoPrev )
     640             :                 {
     641             :                     SwRedlineData aData(rFltRedline.eTypePrev,
     642             :                                         rFltRedline.nAutorNoPrev,
     643             :                                         rFltRedline.aStampPrev,
     644             :                                         OUString(),
     645             :                                         0
     646           0 :                                         );
     647           0 :                     pDoc->getIDocumentRedlineAccess().AppendRedline(new SwRangeRedline(aData, aRegion), true);
     648             :                 }
     649             :                 SwRedlineData aData(rFltRedline.eType,
     650             :                                     rFltRedline.nAutorNo,
     651             :                                     rFltRedline.aStamp,
     652             :                                     OUString(),
     653             :                                     0
     654           0 :                                     );
     655           0 :                 pDoc->getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline(aData, aRegion), true );
     656           0 :                 pDoc->getIDocumentRedlineAccess().SetRedlineMode((RedlineMode_t)( nsRedlineMode_t::REDLINE_NONE
     657             :                                                 | nsRedlineMode_t::REDLINE_SHOW_INSERT
     658           0 :                                                 | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
     659             :             }
     660             :         }
     661           0 :         break;
     662             :     default:
     663             :         {
     664             :             // Revised for more complex situations should be considered
     665       45148 :             if ( !bSdODChecked )
     666             :             {
     667         312 :                 bHasSdOD = HasSdOD();
     668         312 :                 bSdODChecked = true;
     669             :             }
     670       45148 :             sal_Int32 nStart = rEntry.GetStartCP();
     671       45148 :             sal_Int32 nEnd = rEntry.GetEndCP();
     672       45148 :             if (nStart != -1 && nEnd != -1 && nEnd >= nStart )
     673             :             {
     674       45148 :                 rEntry.SetIsParaEnd( IsParaEndInCPs(nStart,nEnd,bHasSdOD) );
     675             :             }
     676       45148 :             if (rEntry.MakeRegion(pDoc, aRegion, false))
     677             :             {
     678       39516 :                 nStart = rEntry.GetStartCP();
     679       39516 :                 nEnd = rEntry.GetEndCP();
     680       39516 :                 if (rEntry.IsParaEnd())
     681             :                 {
     682        5844 :                     pDoc->getIDocumentContentOperations().InsertPoolItem(aRegion, *rEntry.pAttr, 0, true);
     683             :                 }
     684             :                 else
     685             :                 {
     686       33672 :                     pDoc->getIDocumentContentOperations().InsertPoolItem(aRegion, *rEntry.pAttr, 0);
     687             :                 }
     688             :             }
     689             :         }
     690       45148 :         break;
     691       45390 :     }
     692       45390 : }
     693             : 
     694           0 : bool SwFltControlStack::IsParaEndInCPs(sal_Int32 /*nStart*/, sal_Int32 /*nEnd*/,bool /*bSdOD*/) const
     695             : {
     696           0 :     return false;
     697             : }
     698             : 
     699           0 : bool SwFltControlStack::CheckSdOD(sal_Int32 /*nStart*/, sal_Int32 /*nEnd*/)
     700             : {
     701           0 :     return false;
     702             : }
     703             : 
     704          16 : SfxPoolItem* SwFltControlStack::GetFmtStackAttr(sal_uInt16 nWhich, sal_uInt16 * pPos)
     705             : {
     706          16 :     size_t nSize = maEntries.size();
     707             : 
     708          16 :     while (nSize)
     709             :     {
     710             :         // is it the looked-for attribute ? (only applies to locked, meaning
     711             :         // currently set attributes!!)
     712          16 :         SwFltStackEntry &rEntry = maEntries[--nSize];
     713          16 :         if (rEntry.bOpen && rEntry.pAttr->Which() == nWhich)
     714             :         {
     715          16 :             if (pPos)
     716          16 :                 *pPos = nSize;
     717          16 :             return (SfxPoolItem*)rEntry.pAttr;      // Ok, so stop
     718             :         }
     719             :     }
     720           0 :     return 0;
     721             : }
     722             : 
     723           0 : const SfxPoolItem* SwFltControlStack::GetOpenStackAttr(const SwPosition& rPos, sal_uInt16 nWhich)
     724             : {
     725           0 :     SwFltPosition aFltPos(rPos);
     726             : 
     727           0 :     size_t nSize = maEntries.size();
     728             : 
     729           0 :     while (nSize)
     730             :     {
     731           0 :         SwFltStackEntry &rEntry = maEntries[--nSize];
     732           0 :         if (rEntry.bOpen && rEntry.pAttr->Which() == nWhich && rEntry.m_aMkPos == aFltPos)
     733             :         {
     734           0 :             return (SfxPoolItem*)rEntry.pAttr;
     735             :         }
     736             :     }
     737           0 :     return 0;
     738             : }
     739             : 
     740           2 : void SwFltControlStack::Delete(const SwPaM &rPam)
     741             : {
     742           2 :     const SwPosition *pStt = rPam.Start(), *pEnd = rPam.End();
     743             : 
     744           2 :     if( !rPam.HasMark() || *pStt >= *pEnd )
     745           0 :         return;
     746             : 
     747           2 :     SwNodeIndex aStartNode(pStt->nNode, -1);
     748           2 :     const sal_Int32 nStartIdx = pStt->nContent.GetIndex();
     749           4 :     SwNodeIndex aEndNode(pEnd->nNode, -1);
     750           2 :     const sal_Int32 nEndIdx = pEnd->nContent.GetIndex();
     751             : 
     752             :     // We don't support deleting content that is over one node, or removing a node.
     753             :     OSL_ENSURE(aEndNode == aStartNode, "nodes must be the same, or this method extended");
     754           2 :     if (aEndNode != aStartNode)
     755           0 :         return;
     756             : 
     757           4 :     for (size_t nSize = maEntries.size(); nSize > 0;)
     758             :     {
     759           0 :         SwFltStackEntry& rEntry = maEntries[--nSize];
     760             : 
     761             :         bool bEntryStartAfterSelStart =
     762           0 :             (rEntry.m_aMkPos.m_nNode == aStartNode &&
     763           0 :              rEntry.m_aMkPos.m_nCntnt >= nStartIdx);
     764             : 
     765             :         bool bEntryStartBeforeSelEnd =
     766           0 :             (rEntry.m_aMkPos.m_nNode == aEndNode &&
     767           0 :              rEntry.m_aMkPos.m_nCntnt <= nEndIdx);
     768             : 
     769           0 :         bool bEntryEndAfterSelStart = false;
     770           0 :         bool bEntryEndBeforeSelEnd = false;
     771           0 :         if (!rEntry.bOpen)
     772             :         {
     773             :             bEntryEndAfterSelStart =
     774           0 :                 (rEntry.m_aPtPos.m_nNode == aStartNode &&
     775           0 :                  rEntry.m_aPtPos.m_nCntnt >= nStartIdx);
     776             : 
     777             :             bEntryEndBeforeSelEnd =
     778           0 :                 (rEntry.m_aPtPos.m_nNode == aEndNode &&
     779           0 :                  rEntry.m_aPtPos.m_nCntnt <= nEndIdx);
     780             :         }
     781             : 
     782           0 :         bool bTotallyContained = false;
     783           0 :         if (
     784           0 :              bEntryStartAfterSelStart && bEntryStartBeforeSelEnd &&
     785           0 :              bEntryEndAfterSelStart && bEntryEndBeforeSelEnd
     786             :            )
     787             :         {
     788           0 :            bTotallyContained = true;
     789             :         }
     790             : 
     791           0 :         if (bTotallyContained)
     792             :         {
     793             :             // after start, before end, delete
     794           0 :             DeleteAndDestroy(nSize);
     795           0 :             continue;
     796             :         }
     797             : 
     798           0 :         const sal_Int32 nCntntDiff = nEndIdx - nStartIdx;
     799             : 
     800             :         // to be adjusted
     801           0 :         if (bEntryStartAfterSelStart)
     802             :         {
     803           0 :             if (bEntryStartBeforeSelEnd)
     804             :             {
     805             :                 // move start to new start
     806           0 :                 rEntry.m_aMkPos.SetPos(aStartNode, nStartIdx);
     807             :             }
     808             :             else
     809           0 :                 rEntry.m_aMkPos.m_nCntnt -= nCntntDiff;
     810             :         }
     811             : 
     812           0 :         if (bEntryEndAfterSelStart)
     813             :         {
     814           0 :             if (bEntryEndBeforeSelEnd)
     815           0 :                 rEntry.m_aPtPos.SetPos(aStartNode, nStartIdx);
     816             :             else
     817           0 :                 rEntry.m_aPtPos.m_nCntnt -= nCntntDiff;
     818             :         }
     819             : 
     820             :         //That's what Open is, end equal to start, and nPtCntnt is invalid
     821           0 :         if (rEntry.bOpen)
     822           0 :             rEntry.m_aPtPos = rEntry.m_aMkPos;
     823           2 :     }
     824             : }
     825             : 
     826             : // methods of SwFltAnchor follow
     827         194 : SwFltAnchor::SwFltAnchor(SwFrmFmt* pFmt) :
     828         194 :     SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(pFmt)
     829             : {
     830         194 :     pClient = new SwFltAnchorClient(this);
     831         194 :     pFrmFmt->Add(pClient);
     832         194 : }
     833             : 
     834         194 : SwFltAnchor::SwFltAnchor(const SwFltAnchor& rCpy) :
     835         194 :     SfxPoolItem(RES_FLTR_ANCHOR), pFrmFmt(rCpy.pFrmFmt)
     836             : {
     837         194 :     pClient = new SwFltAnchorClient(this);
     838         194 :     pFrmFmt->Add(pClient);
     839         194 : }
     840             : 
     841         970 : SwFltAnchor::~SwFltAnchor()
     842             : {
     843         388 :     delete pClient;
     844         582 : }
     845             : 
     846           0 : void SwFltAnchor::SetFrmFmt(SwFrmFmt * _pFrmFmt)
     847             : {
     848           0 :     pFrmFmt = _pFrmFmt;
     849           0 : }
     850             : 
     851             : 
     852             : 
     853           0 : bool SwFltAnchor::operator==(const SfxPoolItem& rItem) const
     854             : {
     855           0 :     return pFrmFmt == ((SwFltAnchor&)rItem).pFrmFmt;
     856             : }
     857             : 
     858         194 : SfxPoolItem* SwFltAnchor::Clone(SfxItemPool*) const
     859             : {
     860         194 :     return new SwFltAnchor(*this);
     861             : }
     862             : 
     863         388 : SwFltAnchorClient::SwFltAnchorClient(SwFltAnchor * pFltAnchor)
     864         388 : : m_pFltAnchor(pFltAnchor)
     865             : {
     866         388 : }
     867             : 
     868          38 : void  SwFltAnchorClient::Modify(const SfxPoolItem *, const SfxPoolItem * pNew)
     869             : {
     870          38 :     if (pNew->Which() == RES_FMT_CHG)
     871             :     {
     872           0 :         const SwFmtChg * pFmtChg = dynamic_cast<const SwFmtChg *> (pNew);
     873             : 
     874           0 :         if (pFmtChg != NULL)
     875             :         {
     876           0 :             SwFrmFmt * pFrmFmt = dynamic_cast<SwFrmFmt *> (pFmtChg->pChangedFmt);
     877             : 
     878           0 :             if (pFrmFmt != NULL)
     879           0 :                 m_pFltAnchor->SetFrmFmt(pFrmFmt);
     880             :         }
     881             :     }
     882          38 : }
     883             : 
     884             : // methods of SwFltRedline follow
     885           0 : bool SwFltRedline::operator==(const SfxPoolItem& rItem) const
     886             : {
     887           0 :     return this == &rItem;
     888             : }
     889             : 
     890          10 : SfxPoolItem* SwFltRedline::Clone( SfxItemPool* ) const
     891             : {
     892          10 :     return new SwFltRedline(*this);
     893             : }
     894             : 
     895             : // methods of SwFltBookmark follow
     896          48 : SwFltBookmark::SwFltBookmark( const OUString& rNa, const OUString& rVa,
     897             :                               long nHand, const bool bIsTOCBookmark )
     898             :     : SfxPoolItem( RES_FLTR_BOOKMARK )
     899             :     , mnHandle( nHand )
     900             :     , maName( rNa )
     901             :     , maVal( rVa )
     902          48 :     , mbIsTOCBookmark( bIsTOCBookmark )
     903             : {
     904             :     // eSrc: CHARSET_DONTKNOW for no transform at operator <<
     905             :     // Upcase is always done.
     906             :     // Transform is never done at XXXStack.NewAttr(...).
     907             :     // otherwise: Src Charset from argument for aName
     908             :     // Src Charset from filter for aVal ( Text )
     909             : 
     910          48 :     if ( IsTOCBookmark() )
     911             :     {
     912           0 :         maName = IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix();
     913           0 :         maName += rNa;
     914             :     }
     915          48 : }
     916             : 
     917          48 : SwFltBookmark::SwFltBookmark(const SwFltBookmark& rCpy)
     918             :     : SfxPoolItem( RES_FLTR_BOOKMARK )
     919             :     , mnHandle( rCpy.mnHandle )
     920             :     , maName( rCpy.maName )
     921             :     , maVal( rCpy.maVal )
     922          48 :     , mbIsTOCBookmark( rCpy.mbIsTOCBookmark )
     923             : {
     924          48 : }
     925             : 
     926           0 : bool SwFltBookmark::operator==(const SfxPoolItem& rItem) const
     927             : {
     928           0 :     return ( maName == ((SwFltBookmark&)rItem).maName)
     929           0 :             && (mnHandle == ((SwFltBookmark&)rItem).mnHandle);
     930             : }
     931             : 
     932          48 : SfxPoolItem* SwFltBookmark::Clone(SfxItemPool*) const
     933             : {
     934          48 :     return new SwFltBookmark(*this);
     935             : }
     936             : 
     937             : // methods of SwFltTOX follow
     938           0 : SwFltTOX::SwFltTOX(SwTOXBase* pBase, sal_uInt16 _nCols)
     939             :     : SfxPoolItem(RES_FLTR_TOX), pTOXBase(pBase), nCols( _nCols ),
     940           0 :       bHadBreakItem( false ), bHadPageDescItem( false )
     941             : {
     942           0 : }
     943             : 
     944           0 : SwFltTOX::SwFltTOX(const SwFltTOX& rCpy)
     945             :     : SfxPoolItem(RES_FLTR_TOX), pTOXBase(rCpy.pTOXBase), nCols( rCpy.nCols ),
     946           0 :       bHadBreakItem( rCpy.bHadBreakItem ), bHadPageDescItem( rCpy.bHadPageDescItem )
     947             : {
     948           0 : }
     949             : 
     950           0 : bool SwFltTOX::operator==(const SfxPoolItem& rItem) const
     951             : {
     952           0 :     return pTOXBase == ((SwFltTOX&)rItem).pTOXBase;
     953             : }
     954             : 
     955           0 : SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const
     956             : {
     957           0 :     return new SwFltTOX(*this);
     958             : }
     959             : 
     960             : // UpdatePageDescs needs to be called at end of parsing to make Writer actually
     961             : // accept Pagedescs contents
     962         186 : void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset)
     963             : {
     964             :     // Update document page descriptors (only this way also left pages
     965             :     // get adjusted)
     966             : 
     967             :     // PageDesc "Standard"
     968         186 :     rDoc.ChgPageDesc(0, rDoc.GetPageDesc(0));
     969             : 
     970             :     // PageDescs "Convert..."
     971         222 :     for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i)
     972          36 :         rDoc.ChgPageDesc(i, rDoc.GetPageDesc(i));
     973         456 : }
     974             : 
     975             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10