LCOV - code coverage report
Current view: top level - sw/source/core/attr - calbck.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 225 253 88.9 %
Date: 2014-11-03 Functions: 33 39 84.6 %
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             : static SwClientIter* pClientIters = 0;
      27             : 
      28    11237609 : TYPEINIT0( SwClient );
      29             : 
      30    12899818 : SwClient::SwClient( SwModify* pToRegisterIn )
      31    12899818 :     : pLeft( 0 ), pRight( 0 ), pRegisteredIn( 0 ), mbIsAllowedToBeRemovedInModifyCall( false )
      32             : {
      33    12899818 :     if(pToRegisterIn)
      34             :         // connect to SwModify
      35     1403160 :         pToRegisterIn->Add(this);
      36    12899818 : }
      37             : 
      38      206571 : void SwClient::CheckRegistration( const SfxPoolItem* pOld, const SfxPoolItem* )
      39             : {
      40             :     // this method only handles notification about dying SwModify objects
      41      206571 :     if( (!pOld || pOld->Which() != RES_OBJECTDYING) )
      42      195873 :         return;
      43             : 
      44       10698 :     const SwPtrMsgPoolItem* pDead = static_cast<const SwPtrMsgPoolItem*>(pOld);
      45       10698 :     if(pDead && pDead->pObject == pRegisteredIn)
      46             :     {
      47             :         // I've got a notification from the object I know
      48       10698 :         SwModify* pAbove = const_cast<SwModify*>(pRegisteredIn->GetRegisteredIn());
      49       10698 :         if(pAbove)
      50             :         {
      51             :             // if the dying object itself was listening at an SwModify, I take over
      52             :             // adding myself to pAbove will automatically remove me from my current pRegisteredIn
      53          41 :             pAbove->Add(this);
      54          41 :             return;
      55             :         }
      56             :         // destroy connection
      57       10657 :         pRegisteredIn->Remove(this);
      58             :     }
      59             : }
      60             : 
      61      167108 : void SwClient::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
      62             : {
      63      167108 :     CheckRegistration( pOldValue, pNewValue );
      64      167108 : }
      65             : 
      66        1500 : void SwClient::SwClientNotify( const SwModify&, const SfxHint& )
      67             : {
      68        1500 : }
      69             : 
      70    16391129 : SwClient::~SwClient()
      71             : {
      72             :     OSL_ENSURE( !pRegisteredIn || pRegisteredIn->GetDepends(), "SwModify still known, but Client already disconnected!" );
      73    16391129 :     if( pRegisteredIn && pRegisteredIn->GetDepends() )
      74             :         // still connected
      75     1195609 :         pRegisteredIn->Remove( this );
      76    16391129 : }
      77             : 
      78        5320 : bool SwClient::GetInfo( SfxPoolItem& ) const
      79             : {
      80        5320 :     return true;
      81             : }
      82             : 
      83      199008 : SwModify::SwModify()
      84      199008 :     : SwClient(0), pRoot(0)
      85             : {
      86      199008 :     bModifyLocked = false;
      87      199008 :     bLockClientList = false;
      88      199008 :     bInDocDTOR = false;
      89      199008 :     bInCache = false;
      90      199008 :     bInSwFntCache = false;
      91      199008 : }
      92             : 
      93     1052290 : SwModify::SwModify( SwModify* pToRegisterIn )
      94     1052290 :     : SwClient( pToRegisterIn ), pRoot( 0 )
      95             : {
      96     1052290 :     bModifyLocked = false;
      97     1052290 :     bLockClientList = false;
      98     1052290 :     bInDocDTOR = false;
      99     1052290 :     bInCache = false;
     100     1052290 :     bInSwFntCache = false;
     101     1052290 : }
     102             : 
     103     2501480 : SwModify::~SwModify()
     104             : {
     105             :     OSL_ENSURE( !IsModifyLocked(), "Modify destroyed but locked." );
     106             : 
     107     1250740 :     if ( IsInCache() )
     108       28036 :         SwFrm::GetCache().Delete( this );
     109             : 
     110     1250740 :     if ( IsInSwFntCache() )
     111           0 :         pSwFontCache->Delete( this );
     112             : 
     113     1250740 :     if( pRoot )
     114             :     {
     115             :         // there are depending objects
     116      558329 :         if( IsInDocDTOR() )
     117             :         {
     118             :             // If the document gets destroyed anyway, just tell clients to
     119             :             // forget me so that they don't try to get removed from my list
     120             :             // later when they also get destroyed
     121         250 :             SwClientIter aIter( *this );
     122         250 :             SwClient* p = aIter.GoStart();
     123        1155 :             while ( p )
     124             :             {
     125         655 :                 p->pRegisteredIn = 0;
     126         655 :                 p = ++aIter;
     127         250 :             }
     128             :         }
     129             :         else
     130             :         {
     131             :             // notify all clients that they shall remove themselves
     132      558079 :             SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
     133      558079 :             NotifyClients( &aDyObject, &aDyObject );
     134             : 
     135             :             // remove all clients that have not done themselves
     136             :             // mba: possibly a hotfix for forgotten base class calls?!
     137     1126664 :             while( pRoot )
     138      568585 :                 pRoot->CheckRegistration( &aDyObject, &aDyObject );
     139             :         }
     140             :     }
     141     1250740 : }
     142             : 
     143      165715 : void SwModify::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     144             : {
     145      165715 :     NotifyClients( pOldValue, pNewValue );
     146      165715 : }
     147             : 
     148     3162221 : void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     149             : {
     150     3162221 :     if ( IsInCache() || IsInSwFntCache() )
     151             :     {
     152             :         const sal_uInt16 nWhich = pOldValue ? pOldValue->Which() :
     153       53904 :                                         pNewValue ? pNewValue->Which() : 0;
     154       53904 :         CheckCaching( nWhich );
     155             :     }
     156             : 
     157     3162221 :     if ( !pRoot || IsModifyLocked() )
     158     4843032 :         return;
     159             : 
     160     1481410 :     LockModify();
     161             : 
     162             :     // mba: WTF?!
     163     1481410 :     if( !pOldValue )
     164             :     {
     165      149030 :         bLockClientList = true;
     166             :     }
     167             :     else
     168             :     {
     169     1332380 :         switch( pOldValue->Which() )
     170             :         {
     171             :         case RES_OBJECTDYING:
     172             :         case RES_REMOVE_UNO_OBJECT:
     173      560430 :             bLockClientList = ((SwPtrMsgPoolItem*)pOldValue)->pObject != this;
     174      560430 :             break;
     175             : 
     176             :         default:
     177      771950 :             bLockClientList = true;
     178             :         }
     179             :     }
     180             : 
     181     1481410 :     ModifyBroadcast( pOldValue, pNewValue );
     182     1481410 :     bLockClientList = false;
     183     1481410 :     UnlockModify();
     184             : }
     185             : 
     186      283042 : bool SwModify::GetInfo( SfxPoolItem& rInfo ) const
     187             : {
     188      283042 :     bool bRet = true;       // means: continue with next
     189             : 
     190      283042 :     if( pRoot )
     191             :     {
     192      128513 :         SwClientIter aIter( *(SwModify*)this );
     193             : 
     194      128513 :         SwClient* pLast = aIter.GoStart();
     195      128513 :         if( pLast )
     196             :         {
     197      128513 :             while( ( bRet = pLast->GetInfo( rInfo ) ) &&
     198             :                    0 != ( pLast = ++aIter ) )
     199             :                 ;
     200      128513 :         }
     201             :     }
     202             : 
     203      283042 :     return bRet;
     204             : }
     205             : 
     206     2365631 : void SwModify::Add( SwClient* pDepend )
     207             : {
     208             :     OSL_ENSURE( !bLockClientList, "Client inserted while in Modify" );
     209             : 
     210     2365631 :     if(pDepend->pRegisteredIn != this )
     211             :     {
     212             : #if OSL_DEBUG_LEVEL > 0
     213             :         SwClientIter* pTmp = pClientIters;
     214             :         while( pTmp )
     215             :         {
     216             :             OSL_ENSURE( &pTmp->GetModify() != pRoot, "Client added to active ClientIter" );
     217             :             pTmp = pTmp->pNxtIter;
     218             :         }
     219             : #endif
     220             :         // deregister new client in case it is already registered elsewhere
     221     2203150 :         if( pDepend->pRegisteredIn != 0 )
     222      151902 :             pDepend->pRegisteredIn->Remove( pDepend );
     223             : 
     224     2203150 :         if( !pRoot )
     225             :         {
     226             :             // first client added
     227     1143095 :             pRoot = pDepend;
     228     1143095 :             pRoot->pLeft = 0;
     229     1143095 :             pRoot->pRight = 0;
     230             :         }
     231             :         else
     232             :         {
     233             :             // append client
     234     1060055 :             pDepend->pRight = pRoot->pRight;
     235     1060055 :             pRoot->pRight = pDepend;
     236     1060055 :             pDepend->pLeft = pRoot;
     237     1060055 :             if( pDepend->pRight )
     238      778452 :                 pDepend->pRight->pLeft = pDepend;
     239             :         }
     240             : 
     241             :         // connect client to me
     242     2203150 :         pDepend->pRegisteredIn = this;
     243             :     }
     244     2365631 : }
     245             : 
     246     2202135 : SwClient* SwModify::Remove( SwClient* pDepend )
     247             : {
     248     2202135 :     if ( bInDocDTOR )
     249           0 :         return 0;
     250             : 
     251             :     OSL_ENSURE( !bLockClientList || pDepend->mbIsAllowedToBeRemovedInModifyCall, "SwClient shall be removed in Modify call!" );
     252             : 
     253     2202135 :     if( pDepend->pRegisteredIn == this )
     254             :     {
     255             :         // SwClient is my listener
     256             :         // remove it from my list
     257     2202135 :         SwClient* pR = pDepend->pRight;
     258     2202135 :         SwClient* pL = pDepend->pLeft;
     259     2202135 :         if( pRoot == pDepend )
     260     1374258 :             pRoot = pL ? pL : pR;
     261             : 
     262     2202135 :         if( pL )
     263      827877 :             pL->pRight = pR;
     264     2202135 :         if( pR )
     265      819701 :             pR->pLeft = pL;
     266             : 
     267             :         // update ClientIters
     268     2202135 :         SwClientIter* pTmp = pClientIters;
     269     5011596 :         while( pTmp )
     270             :         {
     271      607326 :             if( pTmp->pAct == pDepend || pTmp->pDelNext == pDepend )
     272             :             {
     273             :                 // if object being removed is the current or next object in an
     274             :                 // iterator, advance this iterator
     275      556591 :                 pTmp->pDelNext = pR;
     276             :             }
     277      607326 :             pTmp = pTmp->pNxtIter;
     278             :         }
     279             : 
     280     2202135 :         pDepend->pLeft = 0;
     281     2202135 :         pDepend->pRight = 0;
     282             :     }
     283             :     else
     284             :     {
     285             :         OSL_FAIL( "SwModify::Remove(): could not find pDepend" );
     286             :     }
     287             : 
     288             :     // disconnect client from me
     289     2202135 :     pDepend->pRegisteredIn = 0;
     290     2202135 :     return pDepend;
     291             : }
     292             : 
     293       58672 : void SwModify::CheckCaching( const sal_uInt16 nWhich )
     294             : {
     295       58672 :     if( isCHRATR( nWhich ) )
     296             :     {
     297           0 :         SetInSwFntCache( false );
     298             :     }
     299             :     else
     300             :     {
     301       58672 :         switch( nWhich )
     302             :         {
     303             :         case RES_OBJECTDYING:
     304             :         case RES_FMT_CHG:
     305             :         case RES_ATTRSET_CHG:
     306       40852 :             SetInSwFntCache( false );
     307             :             // fall through
     308             :         case RES_UL_SPACE:
     309             :         case RES_LR_SPACE:
     310             :         case RES_BOX:
     311             :         case RES_SHADOW:
     312             :         case RES_FRM_SIZE:
     313             :         case RES_KEEP:
     314             :         case RES_BREAK:
     315       41972 :             if( IsInCache() )
     316             :             {
     317       33857 :                 SwFrm::GetCache().Delete( this );
     318       33857 :                 SetInCache( false );
     319             :             }
     320       41972 :             break;
     321             :         }
     322             :     }
     323       58672 : }
     324             : 
     325       11760 : void SwModify::CallSwClientNotify( const SfxHint& rHint ) const
     326             : {
     327       11760 :     SwClientIter aIter(*this);
     328       11760 :     SwClient* pClient = aIter.GoStart();
     329       25138 :     while( pClient )
     330             :     {
     331        1618 :         pClient->SwClientNotify( *this, rHint );
     332        1618 :         pClient = ++aIter;
     333       11760 :     }
     334       11760 : }
     335             : 
     336     1498850 : void SwModify::ModifyBroadcast( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue, TypeId nType )
     337             : {
     338     1498850 :     SwClientIter aIter( *this );
     339     1498850 :     SwClient* pClient = aIter.First( nType );
     340     5483466 :     while( pClient )
     341             :     {
     342     2485766 :         pClient->Modify( pOldValue, pNewValue );
     343     2485766 :         pClient = aIter.Next();
     344     1498850 :     }
     345     1498850 : }
     346             : 
     347      273366 : SwDepend::SwDepend( SwClient* pTellHim, SwModify* pDepend )
     348      273366 :     : SwClient( pDepend )
     349             : {
     350      273366 :     pToTell  = pTellHim;
     351      273366 : }
     352             : 
     353        1984 : void SwDepend::Modify( const SfxPoolItem* pOldValue, const SfxPoolItem* pNewValue )
     354             : {
     355        1984 :     if( pNewValue && pNewValue->Which() == RES_OBJECTDYING )
     356         130 :         CheckRegistration(pOldValue,pNewValue);
     357        1854 :     else if( pToTell )
     358        1854 :         pToTell->ModifyNotification(pOldValue, pNewValue);
     359        1984 : }
     360             : 
     361           0 : void SwDepend::SwClientNotify( const SwModify& rMod, const SfxHint& rHint )
     362             : {
     363           0 :     if ( pToTell )
     364           0 :         pToTell->SwClientNotifyCall( rMod, rHint );
     365           0 : }
     366             : 
     367           8 : bool SwDepend::GetInfo( SfxPoolItem& rInfo ) const
     368             : {
     369           8 :     return pToTell ? pToTell->GetInfo( rInfo ) : true;
     370             : }
     371             : 
     372     3776098 : SwClientIter::SwClientIter( const SwModify& rModify )
     373             :     : rRoot(rModify)
     374             :     , pNxtIter(NULL)
     375     3776098 :     , aSrchId(0)
     376             : {
     377     3776098 :     if( pClientIters )
     378             :     {
     379             :         // append to list of ClientIters
     380      440947 :         SwClientIter* pTmp = pClientIters;
     381     1208696 :         while( pTmp->pNxtIter )
     382      326802 :             pTmp = pTmp->pNxtIter;
     383      440947 :         pTmp->pNxtIter = this;
     384             :     }
     385             :     else
     386     3335151 :         pClientIters = this;
     387             : 
     388     3776098 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     389     3776098 :     pDelNext = pAct;
     390     3776098 : }
     391             : 
     392     3776098 : SwClientIter::~SwClientIter()
     393             : {
     394     3776098 :     if( pClientIters )
     395             :     {
     396             :         // reorganize list of ClientIters
     397     3776098 :         if( pClientIters == this )
     398     3335151 :             pClientIters = pNxtIter;
     399             :         else
     400             :         {
     401      440947 :             SwClientIter* pTmp = pClientIters;
     402     1208696 :             while( pTmp->pNxtIter != this )
     403      326802 :                 if( 0 == ( pTmp = pTmp->pNxtIter ) )
     404             :                 {
     405             :                     OSL_ENSURE( this, "Lost my pointer" );
     406           0 :                     return ;
     407             :                 }
     408      440947 :             pTmp->pNxtIter = pNxtIter;
     409             :         }
     410             :     }
     411     7552196 : }
     412             : 
     413      517360 : SwClient* SwClientIter::operator++()
     414             : {
     415      517360 :     if( pDelNext == pAct )
     416             :     {
     417      517326 :         pAct = pAct->pRight;
     418      517326 :         pDelNext = pAct;
     419             :     }
     420             :     else
     421          34 :         pAct = pDelNext;
     422      517360 :     return pAct;
     423             : }
     424             : 
     425     3771966 : SwClient* SwClientIter::GoStart()
     426             : {
     427     3771966 :     pAct = const_cast<SwClient*>(rRoot.GetDepends());
     428     3771966 :     if( pAct )
     429             :     {
     430     7006408 :         while( pAct->pLeft )
     431           0 :             pAct = pAct->pLeft;
     432             :     }
     433     3771966 :     pDelNext = pAct;
     434     3771966 :     return pAct;
     435             : }
     436             : 
     437         696 : SwClient* SwClientIter::GoEnd()
     438             : {
     439         696 :     pAct = pDelNext;
     440         696 :     if( !pAct )
     441         696 :         pAct = const_cast<SwClient*>(rRoot.GetDepends());
     442         696 :     if( pAct )
     443             :     {
     444           0 :         while( pAct->pRight )
     445           0 :             pAct = pAct->pRight;
     446             :     }
     447         696 :     pDelNext = pAct;
     448         696 :     return pAct;
     449             : }
     450             : 
     451     3611061 : SwClient* SwClientIter::First( TypeId nType )
     452             : {
     453     3611061 :     aSrchId = nType;
     454     3611061 :     GoStart();
     455     3611061 :     if( pAct )
     456     1464915 :         do {
     457     4682028 :             if( pAct->IsA( aSrchId ) )
     458     3217113 :                 break;
     459             : 
     460     1464915 :             if( pDelNext == pAct )
     461             :             {
     462     1464915 :                 pAct = pAct->pRight;
     463     1464915 :                 pDelNext = pAct;
     464             :             }
     465             :             else
     466           0 :                 pAct = pDelNext;
     467             :         } while( pAct );
     468     3611061 :     return pAct;
     469             : }
     470             : 
     471         696 : SwClient* SwClientIter::Last( TypeId nType )
     472             : {
     473         696 :     aSrchId = nType;
     474         696 :     GoEnd();
     475         696 :     if( pAct )
     476           0 :         do {
     477           0 :             if( pAct->IsA( aSrchId ) )
     478           0 :                 break;
     479             : 
     480           0 :             if( pDelNext == pAct )
     481           0 :                 pAct = pAct->pLeft;
     482             :             else
     483           0 :                 pAct = pDelNext->pLeft;
     484           0 :             pDelNext = pAct;
     485             :         } while( pAct );
     486         696 :     return pAct;
     487             : }
     488             : 
     489     3223769 : SwClient* SwClientIter::Next()
     490             : {
     491     2084969 :     do {
     492     3223769 :         if( pDelNext == pAct )
     493             :         {
     494     2667264 :             pAct = pAct->pRight;
     495     2667264 :             pDelNext = pAct;
     496             :         }
     497             :         else
     498      556505 :             pAct = pDelNext;
     499             : 
     500     3223769 :         if( pAct && pAct->IsA( aSrchId ) )
     501     1138800 :             break;
     502             :     } while( pAct );
     503     3017946 :     return pAct;
     504             : }
     505             : 
     506           0 : SwClient* SwClientIter::Previous()
     507             : {
     508           0 :     do {
     509           0 :         if( pDelNext == pAct )
     510           0 :             pAct = pAct->pLeft;
     511             :         else
     512           0 :             pAct = pDelNext->pLeft;
     513           0 :         pDelNext = pAct;
     514             : 
     515           0 :         if( pAct && pAct->IsA( aSrchId ) )
     516           0 :             break;
     517             :     } while( pAct );
     518           0 :     return pAct;
     519         270 : }
     520             : 
     521             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10