LCOV - code coverage report
Current view: top level - sw/source/core/attr - calbck.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 105 108 97.2 %
Date: 2015-06-13 12:38:46 Functions: 16 21 76.2 %
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 <frame.hxx>
      21             : #include <hintids.hxx>
      22             : #include <hints.hxx>
      23             : #include <swcache.hxx>
      24             : #include <swfntcch.hxx>
      25             : 
      26      660090 : sw::LegacyModifyHint::~LegacyModifyHint() {}
      27             : 
      28     2078486 : TYPEINIT0( SwClient );
      29             : 
      30    18341972 : SwClient::~SwClient()
      31             : {
      32             :     OSL_ENSURE( !pRegisteredIn || pRegisteredIn->HasWriterListeners(), "SwModify still known, but Client already disconnected!" );
      33     9170986 :     if( pRegisteredIn && pRegisteredIn->HasWriterListeners() )
      34      979952 :         pRegisteredIn->Remove( this );
      35     9170986 : }
      36             : 
      37      132897 : void SwClient::CheckRegistration( const SfxPoolItem* pOld, const SfxPoolItem* )
      38             : {
      39             :     // this method only handles notification about dying SwModify objects
      40      132897 :     if( (!pOld || pOld->Which() != RES_OBJECTDYING) )
      41      126730 :         return;
      42             : 
      43        6167 :     const SwPtrMsgPoolItem* pDead = static_cast<const SwPtrMsgPoolItem*>(pOld);
      44        6167 :     if(pDead && pDead->pObject == pRegisteredIn)
      45             :     {
      46             :         // I've got a notification from the object I know
      47        6130 :         SwModify* pAbove = pRegisteredIn->GetRegisteredIn();
      48        6130 :         if(pAbove)
      49             :         {
      50             :             // if the dying object itself was listening at an SwModify, I take over
      51             :             // adding myself to pAbove will automatically remove me from my current pRegisteredIn
      52          41 :             pAbove->Add(this);
      53          41 :             return;
      54             :         }
      55             :         // destroy connection
      56        6089 :         pRegisteredIn->Remove(this);
      57             :     }
      58             : }
      59             : 
      60     1291592 : void SwClient::SwClientNotify(const SwModify&, const SfxHint& rHint)
      61             : {
      62     1291592 :     if (typeid(rHint) == typeid(sw::LegacyModifyHint))
      63             :     {
      64     1238605 :         auto pLegacyHint(static_cast<const sw::LegacyModifyHint*>(&rHint));
      65     1238605 :         Modify(pLegacyHint->m_pOld, pLegacyHint->m_pNew);
      66             :     }
      67     1291592 : };
      68             : 
      69      108824 : void SwClient::Modify(SfxPoolItem const*const pOldValue, SfxPoolItem const*const pNewValue)
      70             : {
      71      108824 :     CheckRegistration( pOldValue, pNewValue );
      72      108824 : }
      73             : 
      74     2119486 : SwModify::~SwModify()
      75             : {
      76             :     OSL_ENSURE( !IsModifyLocked(), "Modify destroyed but locked." );
      77             : 
      78     1059743 :     if ( IsInCache() )
      79       15518 :         SwFrm::GetCache().Delete( this );
      80             : 
      81     1059743 :     if ( IsInSwFntCache() )
      82           0 :         pSwFontCache->Delete( this );
      83             : 
      84     1059743 :     if( m_pWriterListeners )
      85             :     {
      86             :         // there are depending objects
      87      113696 :         if( IsInDocDTOR() )
      88             :         {
      89             :             // If the document gets destroyed anyway, just tell clients to
      90             :             // forget me so that they don't try to get removed from my list
      91             :             // later when they also get destroyed
      92         133 :             SwIterator<SwClient,SwModify> aIter(*this);
      93         477 :             for(SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next())
      94         477 :                 pClient->pRegisteredIn = nullptr;
      95             :         }
      96             :         else
      97             :         {
      98             :             // notify all clients that they shall remove themselves
      99      113563 :             SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
     100      113563 :             NotifyClients( &aDyObject, &aDyObject );
     101             : 
     102             :             // remove all clients that have not done themselves
     103             :             // mba: possibly a hotfix for forgotten base class calls?!
     104      233198 :             while( m_pWriterListeners )
     105      119635 :                 static_cast<SwClient*>(m_pWriterListeners)->CheckRegistration( &aDyObject, &aDyObject );
     106             :         }
     107             :     }
     108     1059743 : }
     109             : 
     110     2723583 : void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     111             : {
     112     2723583 :     if ( IsInCache() || IsInSwFntCache() )
     113             :     {
     114             :         const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
     115       31303 :                                         pNewValue ? pNewValue->Which() : 0;
     116       31303 :         CheckCaching( nWhich );
     117             :     }
     118             : 
     119     2723583 :     if ( !m_pWriterListeners || IsModifyLocked() )
     120     4787922 :         return;
     121             : 
     122      659244 :     LockModify();
     123             : 
     124             :     // mba: WTF?!
     125      659244 :     if( !pOldValue )
     126             :     {
     127       79108 :         bLockClientList = true;
     128             :     }
     129             :     else
     130             :     {
     131      580136 :         switch( pOldValue->Which() )
     132             :         {
     133             :         case RES_OBJECTDYING:
     134             :         case RES_REMOVE_UNO_OBJECT:
     135      114915 :             bLockClientList = static_cast<const SwPtrMsgPoolItem*>(pOldValue)->pObject != this;
     136      114915 :             break;
     137             : 
     138             :         default:
     139      465221 :             bLockClientList = true;
     140             :         }
     141             :     }
     142             : 
     143      659244 :     ModifyBroadcast( pOldValue, pNewValue );
     144      659244 :     bLockClientList = false;
     145      659244 :     UnlockModify();
     146             : }
     147             : 
     148     1278958 : bool SwModify::GetInfo( SfxPoolItem& rInfo ) const
     149             : {
     150     1278958 :     if(!m_pWriterListeners)
     151      915819 :         return true;
     152      363139 :     SwIterator<SwClient,SwModify> aIter(*this);
     153     1117100 :     for(SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next())
     154      936625 :         if(!pClient->GetInfo( rInfo ))
     155      182664 :             return false;
     156      180475 :     return true;
     157             : }
     158             : 
     159     1703283 : void SwModify::Add( SwClient* pDepend )
     160             : {
     161             :     OSL_ENSURE( !bLockClientList, "Client inserted while in Modify" );
     162             : 
     163     1703283 :     if(pDepend->pRegisteredIn != this )
     164             :     {
     165             : #if OSL_DEBUG_LEVEL > 0
     166             :         if(sw::ClientIteratorBase::our_pClientIters)
     167             :         {
     168             :             for(auto& rIter : sw::ClientIteratorBase::our_pClientIters->GetRingContainer())
     169             :             {
     170             :                 SAL_WARN_IF(&rIter.m_rRoot == m_pWriterListeners, "sw.core", "a " << typeid(*pDepend).name() << " client added as listener to a " << typeid(*this).name() << " during client iteration.");
     171             :             }
     172             :         }
     173             : #endif
     174             :         // deregister new client in case it is already registered elsewhere
     175     1585837 :         if( pDepend->pRegisteredIn != nullptr )
     176       92952 :             pDepend->pRegisteredIn->Remove( pDepend );
     177             : 
     178     1585837 :         if( !m_pWriterListeners )
     179             :         {
     180             :             // first client added
     181      650280 :             m_pWriterListeners = pDepend;
     182      650280 :             m_pWriterListeners->m_pLeft = nullptr;
     183      650280 :             m_pWriterListeners->m_pRight = nullptr;
     184             :         }
     185             :         else
     186             :         {
     187             :             // append client
     188      935557 :             pDepend->m_pRight = m_pWriterListeners->m_pRight;
     189      935557 :             m_pWriterListeners->m_pRight = pDepend;
     190      935557 :             pDepend->m_pLeft = m_pWriterListeners;
     191      935557 :             if( pDepend->m_pRight )
     192      753584 :                 pDepend->m_pRight->m_pLeft = pDepend;
     193             :         }
     194             : 
     195             :         // connect client to me
     196     1585837 :         pDepend->pRegisteredIn = this;
     197             :     }
     198     1703283 : }
     199             : 
     200     1583015 : SwClient* SwModify::Remove( SwClient* pDepend )
     201             : {
     202     1583015 :     if(m_bInDocDTOR)
     203           0 :         return nullptr;
     204             : 
     205             :     assert(pDepend->pRegisteredIn == this);
     206             : 
     207             :     // SwClient is my listener
     208             :     // remove it from my list
     209     1583015 :     ::sw::WriterListener* pR = pDepend->m_pRight;
     210     1583015 :     ::sw::WriterListener* pL = pDepend->m_pLeft;
     211     1583015 :     if( m_pWriterListeners == pDepend )
     212      804071 :         m_pWriterListeners = pL ? pL : pR;
     213             : 
     214     1583015 :     if( pL )
     215      778944 :         pL->m_pRight = pR;
     216     1583015 :     if( pR )
     217      792430 :         pR->m_pLeft = pL;
     218             : 
     219             :     // update ClientIterators
     220     1583015 :     if(sw::ClientIteratorBase::our_pClientIters)
     221             :     {
     222      595908 :         for(auto& rIter : sw::ClientIteratorBase::our_pClientIters->GetRingContainer())
     223             :         {
     224      304365 :             if( rIter.m_pCurrent == pDepend || rIter.m_pPosition == pDepend )
     225             :             {
     226             :                 // if object being removed is the current or next object in an
     227             :                 // iterator, advance this iterator
     228      274156 :                 rIter.m_pPosition = static_cast<SwClient*>(pR);
     229             :             }
     230             :         }
     231             :     }
     232     1583015 :     pDepend->m_pLeft = nullptr;
     233     1583015 :     pDepend->m_pRight = nullptr;
     234     1583015 :     pDepend->pRegisteredIn = nullptr;
     235     1583015 :     return pDepend;
     236             : }
     237             : 
     238       33821 : void SwModify::CheckCaching( const sal_uInt16 nWhich )
     239             : {
     240       33821 :     if( isCHRATR( nWhich ) )
     241             :     {
     242           0 :         SetInSwFntCache( false );
     243             :     }
     244             :     else
     245             :     {
     246       33821 :         switch( nWhich )
     247             :         {
     248             :         case RES_OBJECTDYING:
     249             :         case RES_FMT_CHG:
     250             :         case RES_ATTRSET_CHG:
     251       23663 :             SetInSwFntCache( false );
     252             :             // fall through
     253             :         case RES_UL_SPACE:
     254             :         case RES_LR_SPACE:
     255             :         case RES_BOX:
     256             :         case RES_SHADOW:
     257             :         case RES_FRM_SIZE:
     258             :         case RES_KEEP:
     259             :         case RES_BREAK:
     260       24256 :             if( IsInCache() )
     261             :             {
     262       19639 :                 SwFrm::GetCache().Delete( this );
     263       19639 :                 SetInCache( false );
     264             :             }
     265       24256 :             break;
     266             :         }
     267             :     }
     268       33821 : }
     269             : 
     270         177 : sw::ClientIteratorBase* sw::ClientIteratorBase::our_pClientIters = nullptr;
     271             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11